【问题标题】:Uncaught Error: Maximum update depth exceeded error with useState()未捕获的错误:useState() 超出最大更新深度错误
【发布时间】:2022-07-11 19:21:01
【问题描述】:

为什么会出现这个错误?

Uncaught Error: Maximum update depth exceeded. This can happen when a component repeatedly calls setState inside componentWillUpdate or componentDidUpdate. React limits the number of nested updates to prevent infinite loops.**

这是我的代码:

const [roles, setRoles] = useState([]);

useLayoutEffect(() => {
  setRoles(["5nxg5wvb"]);
});

请注意,当我使用 useEffect 时会出现相同的错误,并且只有在我将代码更改为以下代码时该错误才会消失:

useLayoutEffect(() => {
  setRoles("5nxg5wvb");
});

任何帮助将不胜感激......

【问题讨论】:

    标签: javascript reactjs react-hooks


    【解决方案1】:

    您需要在setEffect 中提供一个依赖数组,否则它将在every state change 上运行。由于它正在改变状态,这意味着它会运行,这会导致它再次运行,这会导致它再次运行,等等......

    依赖数组告诉它何时运行。一个空数组意味着“在挂载上运行这个效果”,所以它只会运行一次。一个包含变量名的数组意味着,“当这些变量中的任何一个发生变化时运行。”

    useLayoutEffect(() => {
      setRoles("5nxg5wvb");
    }, []);
    

    【讨论】:

    • 当然!我这边的愚蠢错误......非常感谢! :)
    【解决方案2】:

    为什么会出现这个错误?

    因为你使用useEffectuseLayoutEffect,而没有指定钩子的第二个参数,你只放了第一个参数,即回调函数,状态值总是不同的。

    为什么输入["5nxg5wvb"] 不起作用,而输入"5nxg5wvb" 有效?

    1. 因为如果你使用[](一个数组),你会创建一个新对象并在每次重新渲染时将它与前一个对象进行比较(因为你没有指定钩子的第二个参数,但是知道[] === [] 将产生 false 值。
    2. 如果使用""(字符串),React 会直接比较值,如果相同,则不会更新状态,也不会重新渲染。

    如何解决这个问题?

    1. 你可以把钩子的第二个参数这样放,下面的代码将使钩子只运行一次:
    useLayoutEffect(() => {
      setRoles(["5nxg5wvb"]);
    }, []);
    
    1. 像这样直接把新的值放到useState上就行了,不用把useEffect和静态数据放在一起:
    const [roles, setRoles] = useState(["5nxg5wvb"]);
    

    如果这两个建议都不适用于您的用例,请提供有关您的用例的更多信息。

    【讨论】:

      猜你喜欢
      • 2022-06-14
      • 1970-01-01
      • 2020-07-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-20
      • 2021-06-30
      • 2020-11-26
      相关资源
      最近更新 更多