• 用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
    
  • 相关阅读:
    贾鹏芳 二胡演奏家
    php 关于下载中文文件实现
    Android 线程。。
    Hadoop命令行接口运行自己编写的类
    ubuntu下jdk环境变量的设置
    navicat导入sql语句文件失败原因-----datetime
    sql server获取当前时间到秒级和毫秒级的语句
    sql关于group by的问题
    java的equal和==的区别
    win8.1 占用80端口问题
  • 原文地址:https://www.cnblogs.com/baebae996/p/14403291.html
Copyright © 2020-2023  润新知