【问题标题】:Why setState(hook) in function component cause an infinite loop?为什么函数组件中的 setState(hook) 会导致无限循环?
【发布时间】:2020-06-04 22:04:46
【问题描述】:

代码如下:

import React, { useState } from 'react'

function App() {
  const [a, setA] = useState(1)
  setA(2)
  return (
    <div>
      <h1>{a}</h1>
    </div>
  );
}

错误。太多的重新渲染。 React 限制渲染次数以防止无限循环。

为什么会导致死循环?

我认为原因是函数组件只是作为一个渲染函数,所以setStaterender函数中会导致死循环。

官方有解释吗?

【问题讨论】:

  • 如果您更新状态 - 您的组件会再次重新渲染,并且每次重新渲染组件时都会调用 setA 函数。

标签: javascript reactjs react-hooks


【解决方案1】:

在每次状态更新时,React 将重新渲染组件并运行所有函数体,因为 setA(2) 没有包含在任何钩子或函数中,并且是函数/组件体的一部分。 React 将在每个渲染周期执行此操作。这会造成一个无限循环。

在组件挂载时,React 将设置状态并随着状态更新而进行组件更新,再次有状态更新 React 将再次重新渲染组件。这个循环将一直持续到 react 达到重新渲染限制。

您可以通过将状态更新包装在挂钩中来避免这种情况。

import React, { useState } from 'react'

function App() {
  const [a, setA] = useState(1)
  useEffect(() => {
    setA(2)
  },[]);
  
  return (
    <div>
      <h1>{a}</h1>
    </div>
  );
}

【讨论】:

    【解决方案2】:

    当调用setA 时,您实际上会更新状态变量并触发组件的重新渲染。

    当组件重新渲染时,它将调用setA(就在渲染之前)并再次触发重新渲染。

    你能看到无限循环吗?

    传统上,您将状态变量更新为回调(即当用户单击按钮时)或在某些条件下。

    在你的例子中,你可以直接将a设置为2

    function App() {
      const [a, setA] = useState(2)
      return (
        <div>
          <h1>{a}</h1>
        </div>
      );
    }
    

    如果您想使用a = 1 进行第一次渲染,然后立即使用a = 2,您可以使用只执行一次的效果(因为第二个参数为空数组)

    function App() {
      const [a, setA] = useState(2)
      useEffect(() => setA(2), [])
    
      return (
        <div>
          <h1>{a}</h1>
        </div>
      );
    }
    

    【讨论】:

    • 为什么不useEffect(() =&gt; setA(2), [a]) 跳过效果而不是传递空数组?
    • 这取决于您期望的行为,在第二个参数中使用[a],您将在每次更新a 时将a 重置为2,因此a 基本上不会允许具有除2 以外的其他值(它可以在很短的时间内等于其他值,并且将立即采用值2)。使用[],效果只会应用一次,a 可以为下一次渲染取另一个值
    • 谢谢,现在我知道“HOOKS”是什么意思了。它就像功能组件和反应之间的桥梁。
    • 没错,钩子可以让你在功能组件中与 react 的东西(如状态、引用、生命周期方法)进行交互
    【解决方案3】:

    因为你用setA(2)给状态设置了一个新值,所以每次渲染组件时状态都会收到一个新值,迫使组件再次渲染

    【讨论】:

      猜你喜欢
      • 2021-02-13
      • 1970-01-01
      • 1970-01-01
      • 2013-06-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多