【React hooks】useEffect

68 阅读2分钟

参数介绍

  • 第一个参数为副作用函数
  • 第二个参数为依赖项
import { useState, useEffect } from 'react'

export default function TestEffect() {
    useEffect(()=>{
        console.log('useEffect1')
    })
    useEffect(()=>{
        console.log('useEffect2')
        return ()=>{
            console.log('useEffect2卸载')
        }
    })
    useEffect(()=>{
        console.log('useEffect3')
        return ()=>{
            console.log('useEffect3卸载')
        }
    },[])
  return (
    <div>TestEffect</div>
  )
}

输出:

StrictMode下
useEffect1
useEffect2
useEffect3

StrictMode下
useEffect1
useEffect2
useEffect3
useEffect2卸载
useEffect3卸载
useEffect1
useEffect2
useEffect3

这里只研究下非StrictMode模式,首先执行useEffect将副作用函数加入队列等待执行,挂载后依次执行副作用函数

清理函数

副作用函数的返回值是可选的,一般用来返回一个清理函数,用来清理副作用

清理函数执行时机

清理函数在组件卸载时以及下一次副作用函数调用之前执行

import { useState, useEffect } from 'react'

export default function TestEffect() {
    let [num,setNum] = useState(0)
    useEffect(()=>{
        console.log('useEffect1')
    })
    useEffect(()=>{
        console.log('useEffect2')
        return ()=>{
            console.log('useEffect2卸载')
        }
    })
    useEffect(()=>{
        console.log('useEffect3')
        return ()=>{
            console.log('useEffect3卸载')
        }
    },[])
  return (
    <div>
        <p>{num}</p>
        <button onClick={()=>setNum(++num)}>change</button>
    </div>
  )
}

点击change按钮,依次打印useEffect2卸载useEffect1,useEffect2

import { useState } from "react";
import TestEffect from './TestEffect'

export default function App() {
  let [show,setShow] = useState(true)
  return <div>
    {show && <TestEffect/>}
    <button onClick={()=>setShow(false)}>destroy</button>
  </div>;
}

点击destory按钮,依次打印useEffect2卸载,useEffect3卸载

总结

function FunctionLifecycle(props){
    const [ num , setNum ] = useState(0)
    React.useEffect(()=>{
        /* 请求数据 , 事件监听 , 操纵dom  , 增加定时器 , 延时器 */
        console.log('组件挂载完成:componentDidMount')
        return function componentWillUnmount(){
            /* 解除事件监听器 ,清除 */
            console.log('组件销毁:componentWillUnmount')
        }
    },[])/* 切记 dep = [] */
    React.useEffect(()=>{
        console.log('props变化:componentWillReceiveProps')
    },[ props ])
    React.useEffect(()=>{ /*  */
        console.log(' 组件更新完成:componentDidUpdate ')
    })
    return <div>
        <div> props : { props.number } </div>
        <div> states : { num } </div>
        <button onClick={ ()=> setNum(state=>state + 1) }   >改变state</button>
    </div>
}

export default ()=>{
    const [ number , setNumber ] = React.useState(0)
    const [ isRender , setRender ] = React.useState(true)
    return <div>
        { isRender &&  <FunctionLifecycle number={number}  /> }
        <button onClick={ ()=> setNumber(state => state + 1 ) } > 改变props  </button> <br/>
        <button onClick={()=> setRender(false) } >卸载组件</button>
    </div>
}
  1. useEffect有两个参数,分别为副作用函数,依赖项
  2. 只指定副作用函数,相当于componentDidMountcomponentDidUpdate
  3. 指定副作用函数同时指定依赖项为空数组,相当于componentDidMount
  4. 清理函数会在卸载以及下一次副作用函数调用前执行
  5. 指定依赖项为props,相当于componentDidUpdate