useEffect - 生命周期

在 React 中,function component 和 class component 相比较,function component 是没有生命周期的

我们可以用 useEffect 来代替在 class component 中,一些有关生命周期的操作

我们用一个例子来说明 useEffect 的一些用法和作用

首先有一个 Example 组件,组件里面有一个 button,当点击 button 的时候,可以进行计数

在这个组件里面还有两个 link,Index 和 List

function Example() {
    const [count, setCount] = useState(0);

    return (
        <div>
            <p>You clicked {count} times</p>
            <button onClick={() => { setCount(count + 1) }}>click me</button>

            <Router>
                <ul>
                    <li><Link to="/">Index</Link></li>
                    <li><Link to="/list/">Link</Link></li>
                </ul>
                <Route path="/" component={Index} exact></Route>
                <Route path="/list/" component={List} exact></Route>
            </Router>
        </div>

    )
}

export default Example;
function Index() {
    return (
        <p>this is Index</p>
    )
}
function List() {
    return (
        <p>this is List</p>
    )
}

现在页面上是这样子的

现在给 Index 和 list 分别加上 useEffect

function Index() {
    useEffect(() => {
        console.log("this is Index");
    })
    return (
        <p>this is Index</p>
    )
}
function List() {
    useEffect(() => {
        console.log("this is Link");
    })
    return (
        <p>this is List</p>
    )
}

当页面第一次渲染的时候

点击 Link

可以看出此时 useEffect 有类似 componentDidMount 的作用

现在点击两次 button

可以看到 “this is Link” 又多打印了两次,可以看出 useEffect 有类似 componentDidUpdate 的作用

注意:

  • React 首次渲染和之后的每次渲染都会调用一遍 useEffect 函数,而componentDidMount 表示首次渲染, componentDidUpdate 表示更新导致的重新渲染
  • uesEffect 中定义的函数的执行不会阻碍浏览器更新视图,也就是说这些函数是异步执行的,但是 componentDidMountcomponentDidUpdate 中的代码都是同步执行的

现在,我们给 useEffect 加上一个 return 函数

function Index() {
    useEffect(() => {
        console.log("this is Index");
        return () => {
            console.log("you have leaved Index");
        }
    })
    return (
        <p>this is Index</p>
    )
}
function List() {
    useEffect(() => {
        console.log("this is Link");
        return () => {
            console.log("you have leaved Link");
        }
    })
    return (
        <p>this is List</p>
    )
}

当初次渲染,然后点击 Link 的时候

再切换回 Index

可以看到在组件 unmount 的时候, useEffect 里面的 return 函数被触发了

所以 useEffect 也可以实现 componentWillUnmount 的功能

但是!

当我们点击 button 的时候

可以看到 useEffect 里面的 return 也执行了

但是我们不想让它执行,只是实现 componentWillUnmount 的功能

这时候可以设置 useEffect 的第二个参数

function Index() {
    useEffect(() => {
        console.log("this is Index");
        return () => {
            console.log("you have leaved Index");
        }
    }, [])
    return (
        <p>this is Index</p>
    )
}

这时候点击 button

切换

关于 useEffect 的第二个参数

我们现在给 Example 加一个 useEffect

useEffect(()=>{
  console.log(`useEffect=>You clicked ${count} times`)

   return ()=>{
      console.log('====================')
    }
},[count])

第一次渲染的时候

点击 button 的时候

总结:

  • 当没有 return 的时候
    • 第二个参数是副效应函数的依赖项,只有该变量发生变化的时候,副效应函数才执行
    • 如果第二个参数是一个空数组,表明副效应参数没有任何依赖项,所以,副效应函数这时只会在组件加载进 DOM 后执行一次
  • 当有 return 的时候,return 函数部分
    • 如果没有第二个参数,state 发生变化,组件 unmount 的时候会执行;
    • 如果第二个参数是一个空数组,那么 return 部分和 componentWillUnmount 效果是一样的
    • 如果有依赖项,依赖项发生变化的时候,,useEffect 第一个参数部分都会执行,并且 return 函数先执行
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容