Write a simple countdown page with React hooks

Basic usage of useState

useState is used to add a state to a function component

It takes a parameter as the initial value of the state and returns an array

The first value of the array is the state, and the second value is the function that changes the state

import React, { useState } from 'react'

function stateClass(){

  const [name, setName] = useState('hong')

  return (
    <div>
      <div>hello,{name}</div>
      <button onClick={() => {setName('nihao')}}>click</button>
    </div>
  )
}

export default stateClass

Read status in the component: directly access the status name
Modify the state in the component: call the function and pass in the value after the state is changed

Basic usage of useEffect

useEffect is used to add signals that components have been mounted and to perform (and clean up) side effects

It can receive two parameters: callback function and array

1. Receive only the first parameter:

When componentDidMount is, the callback function is executed

When the state declared by useState is updated (the view is re rendered), the callback function is also executed

2. Receive two parameters: "effect depends on some state s"

The state name defined by useState is written in the array

The callback function is executed only when the status in the array is updated

If we want the callback function to execute only once during componentDidMount, we can write an empty array (called "skip effect")

3. Return value of callback function

The callback function of useEffect allows a function to be returned to clean up side effects

By default (useEffect does not write the second parameter), the returned function will only be executed when the component is unloaded

If useEffect is executed multiple times, the previous effect will be cleaned up before calling a new effect

Example: we want to subscribe to this props. friend. Change of ID:

useEffect(() => {
    // ...
    ChatAPI.subscribeToFriendStatus(props.friend.id, handleStatusChange);
    return () => {
      ChatAPI.unsubscribeFromFriendStatus(props.friend.id, handleStatusChange);
};

The possible action sequences are as follows:

// Mount with { friend: { id: 100 } } props
ChatAPI.subscribeToFriendStatus(100, handleStatusChange);     // Run the first effect

// Update with { friend: { id: 200 } } props
ChatAPI.unsubscribeFromFriendStatus(100, handleStatusChange); // Clear previous effect
ChatAPI.subscribeToFriendStatus(200, handleStatusChange);     // Run the next effect

// Update with { friend: { id: 300 } } props
ChatAPI.unsubscribeFromFriendStatus(200, handleStatusChange); // Clear previous effect
ChatAPI.subscribeToFriendStatus(300, handleStatusChange);     // Run the next effect

// Unmount
ChatAPI.unsubscribeFromFriendStatus(300, handleStatusChange); // Clear last effect

requirement analysis

  • Display the countdown time dynamically and in real time
  • After the countdown, automatically jump to another page

code implementation

First, we need a counter status to indicate the countdown time

There is also a timer ID state, which is used to save the ID of the timer

Secondly, when the page is mounted, you need to create a timer and execute the count-1 operation after 1s

Then clean up the previous timer, create the timer again, and execute count-1 after 1s

We can use the useEffect feature to realize this function:

const [timerID, setTimerID] = useState(null);
const [counter, setCounter] = useState(5);

useEffect(() => {

    if(counter > 0){
      let timer = setTimeout(() => {
        setCounter(counter-1)
      }, 1000);
      setTimerID(timer)
    }else{
      props.history.push('/order')
    }
    
    return () => {
      setTimerID(null)
    }
    
},[counter]);

When the page is mounted: counter = 5, execute the callback function and save the timer ID

After 1s, execute the timer, count = 4

useEffect finds that the count is updated. First clean up the side effects (setTimerID(null)), and then create a new timer

After 1s, execute the timer, count = 3

... In this cycle until count = 0, use react router to jump the page

The complete code is as follows:

import React, {useState,useEffect} from 'react'

function Reminder(props) {
  const [timerID, setTimerID] = useState(null);

  const [counter, setCounter] = useState(5);

  useEffect(() => {

    if(counter > 0){
      let timer = setTimeout(() => {
        setCounter(counter-1)
      }, 1000);
      setTimerID(timer)
    }else{
      props.history.push('/order')
    }
    
    return () => {
      setTimerID(null)
    }
  },[counter]);
  
  return (
    <div>
      <p>{counter}After seconds, it will automatically jump to the order page...</p>
    </div>
  );
  
}

export default Reminder

Tags: React

Posted by tomdude48 on Tue, 19 Apr 2022 05:49:30 +0930