为什么函数组件中的setState(hook)导致无限循环?

时间:2020-02-20 14:36:11

标签: javascript reactjs react-hooks

代码如下:

import React, { useState } from 'react'

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

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

为什么会导致无限循环?

我认为原因是功能组件渲染功能一样,所以当setState中的render时,它将导致无限循环

有官方解释吗?

3 个答案:

答案 0 :(得分:2)

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

在组件安装时,React将设置状态,并在状态更新时进行组件更新,再次有状态更新,React将再次重新渲染组件。该循环将一直持续到反应达到重新渲染限制为止。

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

import React, { useState } from 'react'

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

答案 1 :(得分:1)

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

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

您能看到无限循环吗?

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

在您的示例中,您可以直接将a设置为2

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

如果要使用a = 1进行第一个渲染,然后立即使用a = 2,则可以使用仅执行一次的效果(因为第二个参数为空数组)< / p>

function App() {
  const [a, setA] = useState(2)
  useEffect(() => setA(2), [])

  return (
    <div>
      <h1>{a}</h1>
    </div>
  );
}

答案 2 :(得分:0)

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