useEffect的第二个参数中,哪些变化会导致依赖项更新?

2026-04-02 06:531阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计986个文字,预计阅读时间需要4分钟。

useEffect的第二个参数中,哪些变化会导致依赖项更新?

目录 + useEffect第二个参数 + useEffect规则 + 第二个参数的规则 + 不同值的参数 + 示例 + useEffect使用技巧 + useEffect的第二个参数 + useEffect规则 + 每次render后执行 + 接收第二个参数来控制跳过执行

目录
  • useEffect的第二个参数
    • useEffect规则
    • 第二个参数的规则
    • 不同值的参数
    • 示例
  • useEffect使用技巧

    useEffect的第二个参数

    useEffect规则

    • 在每次render之后执行
    • 接收第二个参数来控制跳过执行,下次render后如果指定的值没有变化就不会执行
    • useEffect时在render之后浏览器已经渲染结束才执行

    第二个参数的规则

    • 它是可选的
    • 类型是一个数组

    不同值的参数

    • 不传参数
    • 空数组
    • 一个值的数组
    • 多个值的数组

    示例

    1. 没有第二个参数时,组件的初始话和更新都会执行

    const [count, setCount] = useState(0) useEffect(() => { console.log("useEffect:", count) })

    2. 空数组时,初始化调用一次之后不再执行,相当于componentDidMount

    const [count, setCount] = useState(0) useEffect(() => { console.log("useEffect:", count) }, [])

    3. 有一个值的数组时,该值有变化就执行

    4. 有多个值的数组时,只要有一个值有变化就执行

    const [count1, setCount1] = useState(0) const [count2, setCount2] = useState(0) useEffect(() => { console.log(count1, count2) }, [count1, count2])

    useEffect使用技巧

    useEffect如果第二个参数的数组不为空,传了多个参数的情况下,使用总结。

    如果第二个传了多个参数,如何查看是那个参数发生了变化呢?请看代码:

    // 在一个正常的Hooks函数中,有如下代码,此代码实现的原理就是通过useRef来达到缓存的目的 const [a, setA] = useState(); const [b, setB] = useState(); const [c, setC] = useState(); const myRef = useRef({a, b, c}); useEffect(() => { const { a: prevA, b: prevB, c: prevC } = myRef.current; if (prevA !== a) { // 证明a发生了变化 } if (prevB !== b) { // 证明b发生了变化 } if (prevC !== c) { // 证明c发生了变化 } }, [a, b, c])

    有时使用useEffect会使组件一直处于不停的刷新,这个是为什么?

    看如下代码,会使组件一直不停的刷新:

    useEffect的第二个参数中,哪些变化会导致依赖项更新?

    const [a, setA] = useState<number[]>([]); useEffect(() => { setA([11]) }, [a]);

    而且此时此刻控制台也抛出了错误,如下图:

    Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
    at Home (localhost:8000/static/umi.js:93407:73)
    at Route
    at Switch
    at Router (localhost:8000/static/umi.js:86181:30)
    at RouterComponent (localhost:8000/static/umi.js:84374:23)
    at Provider (localhost:8000/static/umi.js:73004:20)
    at _DvaContainer (localhost:8000/static/umi.js:90776:5)
    at localhost:8000/static/umi.js:91243:24
    at ./src/.umi/plugin-model/Provider.tsx.__webpack_exports__.default (localhost:8000/static/umi.js:91706:23)

    为何会一直刷新呢?

    因为传给useEffect的第二个参数为引用类型,因为两个引用类型在进行比较的时候永远都是不相等的,以数组为例,声明一个数组就是从Array类上实例化出来了一个新对象,然后JS引擎会为这个对象分配内存空间,所以不同的对象,就会有不同的内存空间,所以两个引用类型的比较永远都是不相等的;例如:

    console.log([] === []); //false,此时注意一下,两个是不相等的

    有了以上的了解,在使用useEffect的时候就应该注意两点:

    1. 第二个参数对应的数组中,尽量避免使用引用类型(此时可以在第一个参数也就是执行的副作用函数中调用setState相关的代码)。

    2.如果第二个参数中用了引用类型,就应该在第一个参数也就是执行的副作用函数中不要用setState相关的代码,要不然会使得组件陷入到死循环中,报上面的错误。

    以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。

    本文共计986个文字,预计阅读时间需要4分钟。

    useEffect的第二个参数中,哪些变化会导致依赖项更新?

    目录 + useEffect第二个参数 + useEffect规则 + 第二个参数的规则 + 不同值的参数 + 示例 + useEffect使用技巧 + useEffect的第二个参数 + useEffect规则 + 每次render后执行 + 接收第二个参数来控制跳过执行

    目录
    • useEffect的第二个参数
      • useEffect规则
      • 第二个参数的规则
      • 不同值的参数
      • 示例
    • useEffect使用技巧

      useEffect的第二个参数

      useEffect规则

      • 在每次render之后执行
      • 接收第二个参数来控制跳过执行,下次render后如果指定的值没有变化就不会执行
      • useEffect时在render之后浏览器已经渲染结束才执行

      第二个参数的规则

      • 它是可选的
      • 类型是一个数组

      不同值的参数

      • 不传参数
      • 空数组
      • 一个值的数组
      • 多个值的数组

      示例

      1. 没有第二个参数时,组件的初始话和更新都会执行

      const [count, setCount] = useState(0) useEffect(() => { console.log("useEffect:", count) })

      2. 空数组时,初始化调用一次之后不再执行,相当于componentDidMount

      const [count, setCount] = useState(0) useEffect(() => { console.log("useEffect:", count) }, [])

      3. 有一个值的数组时,该值有变化就执行

      4. 有多个值的数组时,只要有一个值有变化就执行

      const [count1, setCount1] = useState(0) const [count2, setCount2] = useState(0) useEffect(() => { console.log(count1, count2) }, [count1, count2])

      useEffect使用技巧

      useEffect如果第二个参数的数组不为空,传了多个参数的情况下,使用总结。

      如果第二个传了多个参数,如何查看是那个参数发生了变化呢?请看代码:

      // 在一个正常的Hooks函数中,有如下代码,此代码实现的原理就是通过useRef来达到缓存的目的 const [a, setA] = useState(); const [b, setB] = useState(); const [c, setC] = useState(); const myRef = useRef({a, b, c}); useEffect(() => { const { a: prevA, b: prevB, c: prevC } = myRef.current; if (prevA !== a) { // 证明a发生了变化 } if (prevB !== b) { // 证明b发生了变化 } if (prevC !== c) { // 证明c发生了变化 } }, [a, b, c])

      有时使用useEffect会使组件一直处于不停的刷新,这个是为什么?

      看如下代码,会使组件一直不停的刷新:

      useEffect的第二个参数中,哪些变化会导致依赖项更新?

      const [a, setA] = useState<number[]>([]); useEffect(() => { setA([11]) }, [a]);

      而且此时此刻控制台也抛出了错误,如下图:

      Warning: Maximum update depth exceeded. This can happen when a component calls setState inside useEffect, but useEffect either doesn't have a dependency array, or one of the dependencies changes on every render.
      at Home (localhost:8000/static/umi.js:93407:73)
      at Route
      at Switch
      at Router (localhost:8000/static/umi.js:86181:30)
      at RouterComponent (localhost:8000/static/umi.js:84374:23)
      at Provider (localhost:8000/static/umi.js:73004:20)
      at _DvaContainer (localhost:8000/static/umi.js:90776:5)
      at localhost:8000/static/umi.js:91243:24
      at ./src/.umi/plugin-model/Provider.tsx.__webpack_exports__.default (localhost:8000/static/umi.js:91706:23)

      为何会一直刷新呢?

      因为传给useEffect的第二个参数为引用类型,因为两个引用类型在进行比较的时候永远都是不相等的,以数组为例,声明一个数组就是从Array类上实例化出来了一个新对象,然后JS引擎会为这个对象分配内存空间,所以不同的对象,就会有不同的内存空间,所以两个引用类型的比较永远都是不相等的;例如:

      console.log([] === []); //false,此时注意一下,两个是不相等的

      有了以上的了解,在使用useEffect的时候就应该注意两点:

      1. 第二个参数对应的数组中,尽量避免使用引用类型(此时可以在第一个参数也就是执行的副作用函数中调用setState相关的代码)。

      2.如果第二个参数中用了引用类型,就应该在第一个参数也就是执行的副作用函数中不要用setState相关的代码,要不然会使得组件陷入到死循环中,报上面的错误。

      以上为个人经验,希望能给大家一个参考,也希望大家多多支持易盾网络。