React函数组件Hooks-useEffect详解

748 阅读1分钟

image.png

useEffect(副作用)

副作用

  • 对环境改变即为副作用,如修改document.titl
  • 但是我们不一定非要把副作用放到useEffect
  • 实际上叫afterRender更好,每次render后执行

用途

用途1、作为 componentDidMount 使用,[]做第二个参数,可以用来请求异步数据

代码演示

useEffect(()=>{
    const users = 执行一次()
},[])

用途2、作为 componentDidUpdate 使用,可指定依赖

代码演示

useEffect(()=>{
    console.log("n更新了")
},[n])

用途3、作为 componentWillUnmount 使用,通过return

代码演示

useEffect(() => {
    const subscription = 订阅全国人民吃饭的情报!
    return () => {
        取消订阅全国人民吃饭的情报!
    }
},[])
//////////////////////////////////////////
 const [count, setCount] = useState(0)
    useEffect(() => {
        console.log('use effect...',count)
        const timer = setInterval(() => {
            console.log('timer...count:', count)
            setCount(count + 1)
        }, 1000)
        return ()=> clearInterval(timer)
    },[])

疑问:为什么要取消订阅?

大家都知道,render了之后会执行重新useEffect,如果useEffect里面有一个每setInterval...那么每次render了,再次执行useEffect就会再创建一个setInterval,然后就混乱了...可以把下面案例return的内容删掉感受下

用途4、每次 render 都执行

代码演示

useEffect(() => {
  console.log"每次render都执行")
})

注意事项

注意事项1:useEffect 不能被判断包裹

代码演示

const [count, setCount] = useState(0)
if(2 < 5){
   useEffect(() => {
        console.log('use effect...',count)
        const timer = setInterval(() => setCount(count +1), 1000)
        return ()=> clearInterval(timer)
    }) 
}

注意事项2:useEffect 不能被打断

const [count, setCount] = useState(0)
useEffect(...)

return // 函数提前结束了

useEffect(...)
}

注意事项3:useEffect 里面使用到的state的值, 固定在了useEffect内部, 不会被改变,除非useEffect刷新,重新固定state的值

代码演示

 const [count, setCount] = useState(0)
    useEffect(() => {
        console.log('use effect...',count)
        const timer = setInterval(() => {
            console.log('timer...count:', count)
            setCount(count + 1)
        }, 1000)
        return ()=> clearInterval(timer)
    },[])