useEffect

useEffect的作用是让函数组件具有自己的生命周期钩子函数
useEffect可以看作是class组件中componentDidMount/componentDidUpdate/componentWillUnmount三个生命周期钩子函数的结合体。
useEffect可以接受两个参数,第一个参数是一个回调函数,这个函数,我们叫它effect函数,这个effect函数里面还可以返回一个函数,我们叫它清除函数,第二个参数是一个数组,表示当前useEffect的依赖项
有了 useEffect,我们就可以通过函数组件来实现更为复杂的功能。

在 react hooks 出现之前,主要用类组件来实现复杂功能,因为类组件中有生命周期。

  1. const dependArr = []
  2. useEffect(function effectFunc () {
  3. return function clearFunc () { }
  4. }, dependArr);
  5. //这里effectFunc就是effect函数,clearFunc就是清除函数 dependArr就是依赖项

模拟 componentDidMount

  • 当useEffect的依赖项传递的是一个空数组时,它就相当于componentDidMount,即effect函数仅会在DOM初始化渲染完毕之后执行一次

    1. import React, { useEffect, useState } from 'react'
    2. export default function Hello () {
    3. const [msg, setMsg] = useState("");
    4. useEffect(() => {
    5. //模拟接口发送
    6. setTimeout(() => {
    7. const backendData = 'hello';//假设这是从后台拿的数据
    8. setMsg(backendData);//把数据同步到msg
    9. }, 1000);
    10. }, []);
    11. return (
    12. <div></div>
    13. )
    14. }

    模拟componentDidUpdate

  • useEffect的依赖项如果不传递,则effect函数,会在每次界面更新(包括初始渲染后)的时候执行

  • 如果依赖项传递了有限个依赖,则该函数仅仅会在这些依赖项发生变化时执行。(这种情况下useEffect就相当于 componentDidMount和componentDidUpdate的结合体)

    1. import React, { useState, useEffect } from 'react';
    2. function Hello () {
    3. const [count, setCount] = useState(0);
    4. useEffect(() => {
    5. //如果不传递第二个参数,则界面初始渲染后和以后每次界面更新后都会执行该回调函数
    6. document.title = `You clicked ${count} times`;
    7. });
    8. useEffect(()=>{
    9. document.title = `You clicked ${count} times`;
    10. },[count]);
    11. //如果传递了count,则useEffect只会在count发生变换时执行
    12. return (
    13. <div>
    14. <p>你点了 {count} 次</p>
    15. <button onClick={() => setCount(count + 1)}>
    16. 点我
    17. </button>
    18. </div>
    19. );
    20. }

    模拟componentWillUnMount

    清除函数会在组件卸载的时候,以及effect函数执行(当然effect函数首次执行除外,因为这时清除函数还没有被 返回)之前执行

    1. import React, { useState, useEffect } from 'react';
    2. function Hello () {
    3. const [count, setCount] = useState(0);
    4. useEffect(() => {
    5. console.log("effect函数执行")
    6. const timer = setInterval(() => {
    7. setCount(count => count + 1);
    8. }, 1000);
    9. return () => {
    10. console.log("清除函数执行")
    11. clearInterval(timer);
    12. }
    13. }, []);
    14. //如果依赖项传递的是空数组,则effect函数只会执行一次,并且在组件卸载的时候,清除函数会执行一次
    15. //如果不传,则每次count改变清除函数和effect函数都会执行,具体的执行顺序是页面刚刚渲染完毕的时候
    16. //effect函数会执行一次,接着每当count变化过后,先执行清除函数,在执行effect函数
    17. return (
    18. <div>{count}</div>
    19. )
    20. }