用React hooks寫一個簡單的倒計時頁面


useState的基本用法

useState用於向函數組件添加狀態

它接收一個參數作為狀態的初始值,並返回一個數組

數組的第一個值為狀態,第二個值為改變狀態的函數

import React, { useState } from 'react'

function stateClass(){

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

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

export default stateClass

在組件中讀狀態:直接訪問狀態名即可
在組件中修改狀態:調用函數,傳入狀態改變后的值

useEffect的基本用法

useEffect的作用是:添加組件已掛載的信號,並執行(和清理)副作用

它可以接收2個參數:回調函數、數組

1、只接收第一個參數:

當componentDidMount的時候,執行回調函數

當useState聲明的狀態被更新(視圖重新渲染)后,也執行回調函數

2、接收2個參數:“effect依賴於某一些state”

數組中寫的是用useState定義的狀態名稱

只有當數組中的狀態發生更新時,才執行回調函數

如果我們希望回調函數只在componentDidMount的時候執行一次,就可以寫一個空的數組(稱為“跳過effect")

3、回調函數的返回值

useEffect的回調函數允許返回一個函數,用來清理副作用

默認情況下(useEffect不寫第二個參數),只會在組件卸載(componentWillUnmount)的時候執行這個返回的函數

如果useEffect多次執行,在調用一個新的effect之前會對前一個effect進行清理

例子:我們想要訂閱this.props.friend.id的變化:

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

可能產生的動作序列如下:

// Mount with { friend: { id: 100 } } props
ChatAPI.subscribeToFriendStatus(100, handleStatusChange);     // 運行第一個 effect

// Update with { friend: { id: 200 } } props
ChatAPI.unsubscribeFromFriendStatus(100, handleStatusChange); // 清除上一個 effect
ChatAPI.subscribeToFriendStatus(200, handleStatusChange);     // 運行下一個 effect

// Update with { friend: { id: 300 } } props
ChatAPI.unsubscribeFromFriendStatus(200, handleStatusChange); // 清除上一個 effect
ChatAPI.subscribeToFriendStatus(300, handleStatusChange);     // 運行下一個 effect

// Unmount
ChatAPI.unsubscribeFromFriendStatus(300, handleStatusChange); // 清除最后一個 effect

需求分析

  • 動態地、實時地顯示倒計時的時間
  • 倒計時結束后,自動跳轉到另外一個頁面

代碼實現

首先我們需要一個counter狀態,表示 正在倒數的時間

還有一個timerID狀態,用來保存計時器的ID

其次,當頁面掛載完成的時候,需要創建一個計時器,待1s后執行count-1的操作

然后清理上一個計時器,並再次創建計時器,1s后執行count-1的操作...

我們可以利用useEffect的特性來實現這個功能:

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]);

頁面掛載完成時:counter = 5,執行回調函數,保存計時器ID

1s后,執行計時器,count = 4

useEffect發現count更新,先清理副作用(setTimerID(null)),再新建計時器

1s后,執行計時器,count = 3

...如此循環直到count = 0 時,利用react-router做頁面的跳轉

完整代碼如下:

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}秒后將自動跳轉至訂單頁面...</p>
    </div>
  );
  
}

export default Reminder


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM