React-hooks的useEffect模拟componentDidUpdate生命周期

先回忆一下:

  • class组件中的componentDidUpdate生命周期是初次渲染完后,当接收的props,state改变时或者this.forceUpdate()就会调用
  • 函数组件中的useEffect可以看做 componentDidMount,componentDidUpdate
    和componentWillUnmount 这三个函数的组合

useEffect( ()=>{ } )
只有第一个参数的时候
此时相当于componentDidMount + componentDidUpdate钩子的组合,初次渲染并且状态改变时都会触发

需求:
那么我想通过useEffect模拟componentDidUpdate生命周期,而去掉初次渲染时调用的 componentDidMount

useRef实现

因为初次渲染只会发生一次,可以使用useRef立一个flag解决:

 const mounting = useRef(true);
        useEffect(() => {
    
    
            if (mounting.current) {
    
    
                console.log("初次")
                mounting.current = false;
                return 
            } 

             console.log("DidUpdated")
            
});

useState实现的弊端:

需要注意的是:这个flag不能通过useState去定义,否则setFlag(false)改变状态后,相当于会立马触发一次ComponentDidUpdated钩子

const [Flag, setFlag] = useState(true)

uesEffect(() => {
    
    
    if (Flag) {
    
    
     setFlag(false)
     return
    }
    
})

普通变量实现的问题:

应该有人像我一样想过使用普通变量let flag = true 去做标识吧?
代码如下:

import React, {
    
     useEffect,useState} from 'react'
import {
    
     MyContext } from './Reducer.js'

export default () => {
    
    
    let [num,setNum] = useState(0)
    let flag = true
    
    useEffect(()=>{
    
    
        if(flag){
    
    
            console.log("初次渲染")
            flag = false
            return 
        }

        console.log("componentDidUpdate")

    })
    
    
    return (
        <>
            <button onClick={
    
    ()=>{
    
     setNum(num+1) }}>按钮{
    
    num}</button>
        </>
    )
}

这样是不行的,可以发现一旦调用了setNum()更新了状态,整个函数组件都会被重新调用,也就意味着普通变量flag会重新被初始化为true,一直会走if的逻辑
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/fesfsefgs/article/details/108024853