useEffect

useEffect 是一个 React Hook 函数,用于在 React组件中创建不是由事件引起而是由渲染本身引起的操作,比如发送Ajax请求,更改DOM等等。

1useEffect(() => {}, [])
2
3// 参数1:是一个函数,可以把它叫做副作用函数,在函数内部可以放置要执行的操作。
4// 参数2:是一个数组(可选参),在数组里放置依赖项,不同依赖项会影响第一个参数函数的执行,当是一个空数组的时候,副作用函数只会在组件渲染完毕之后执行一次。
依赖项参数说明

useEffect副作用函数的执行时机存在多种情况,根据传入依赖项的不同,会有不同的执行表现。

依赖项 副作用函数执行时机
没有依赖项 组件初始渲染 + 组件更新时执行
空数组依赖 只在初始渲染时执行一次
添加特定依赖项 组件初始渲染 + 特定依赖项变化时执行

没有依赖项

组件初始渲染 + 组件更新时执行

1import { useEffect, useState } from "react";
2
3export default function App() {
4  let [count, setCount] = useState(0);
5  useEffect(() => {
6    console.log("副作用函数执行了");
7  });
8  return (
9    <>
10      <div>{count}</div>
11      <button onClick={() => setCount(count + 1)}>自增</button>
12    </>
13  );
14}

空数组依赖项

只在初始渲染时执行一次

1import { useEffect, useState } from "react";
2const URL = "http://geek.itheima.net/v1_0/channels";
3export default function App() {
4  let [list, setList] = useState([]);
5  useEffect(() => {
6    async function getList() {
7      const res = await fetch(URL);
8      const jsonRes = await res.json();
9      setList(jsonRes.data.channels);
10    }
11    getList();
12  }, []);
13  return (
14    <>
15      <ul>
16        {list.map((item) => (
17          <li key={item.id}>{item.name}</li>
18        ))}
19      </ul>
20    </>
21  );
22}

添加特定依赖项

组件初始渲染 + 特定依赖项变化时执行

1import { useEffect, useState } from "react";
2
3export default function App() {
4  let [count, setCount] = useState(0);
5  useEffect(() => {
6    console.log("副作用函数执行了");
7  }, [count]);
8  return (
9    <>
10      <div>{count}</div>
11      <button onClick={() => setCount(count + 1)}>自增</button>
12    </>
13  );
14}

清除副作用

在 useEffect 中编写的 由渲染本身引起的对接组件外部的操作,社区也常常把它叫做副作用操作,比如在 useEffect中开起了一个定时器,我们想在组件卸载时把这个定时器再清理掉,这个过程就是清理副作用。

1useEffect(() => {
2  // 实现副作用操作逻辑
3  return () => {
4    // 清除副作用逻辑
5  };
6});

清除副作用的函数最常见的时机是在组件卸载时自动执行。

1import Child from "./Child";
2import { useState } from "react";
3export default function App() {
4  let [isShow, setIsShow] = useState(true);
5  return (
6    <>
7      {isShow && <Child />}
8      <button onClick={() => setIsShow(!isShow)}>卸载子组件</button>
9    </>
10  );
11}
1import { useEffect } from "react";
2export default function Child() {
3  useEffect(() => {
4    let timer = setInterval(() => {
5      console.log("定时器执行中...");
6    }, 1000);
7    return () => {
8      clearInterval(timer);
9    };
10  }, []);
11  return (
12    <div>
13      <h1>子组件</h1>
14    </div>
15  );
16}

:::