React报错之Too many re-renders

2023-02-13 12:04:23 浏览数 (1)

总览

产生"Too many re-renders. React limits the number of renders to prevent an infinite loop"错误有多方面的原因:

  1. 在一个组件的渲染方法中调用一个设置状态的函数。
  2. 立即调用一个事件处理器,而不是传递一个函数。
  3. 有一个无限设置与重渲染的useEffect钩子。

too-many-re-renders-react-limits-the-number.png

这里有个示例来展示错误是如何发生的:

代码语言:javascript复制
import {useState} from 'react';

export default function App() {
  const [counter, setCounter] = useState(0);

  // ⛔️ Too many re-renders. React limits the number
  // of renders to prevent an infinite loop.
  return (
    <div>
      <button onClick={setCounter(counter   1)}>Increment</button>
      <h1>Count: {counter}</h1>
    </div>
  );
}

上述代码问题在于,我们在onClick事件处理器中立即调用了setCounter函数。

该函数是在页面加载时立即被调用,而不是事件触发后调用。

传递函数

为了解决该错误,为onClick事件处理器传递函数,而不是传递调用函数的结果。

代码语言:javascript复制
import {useState} from 'react';

export default function App() {
  const [counter, setCounter] = useState(0);

  return (
    <div>
      <button onClick={() => setCounter(counter   1)}>Increment</button>
      <h1>Count: {counter}</h1>
    </div>
  );
}

现在,我们为事件处理器传递了函数,而不是当页面加载时调用setCounter方法。

如果该方法在页面加载时被调用,就会触发一个setState动作,组件就会无限重新渲染。

如果我们试图立即设置一个组件的状态,而不使用一个条件或事件处理器,也会发生这个错误。

代码语言:javascript复制
import {useState} from 'react';

export default function App() {
  const [counter, setCounter] = useState(0);

  // ⛔️ Too many re-renders. React limits the number
  // of renders to prevent an infinite loop.
  setCounter(counter   1);

  return (
    <div>
      <h1>Count: {counter}</h1>
    </div>
  );
}

问题在于,setCounter函数在组件渲染时被调用、更新状态,并导致重新渲染,而且是无限重新渲染。

你可以通过向useState()钩子传递一个初始值或一个函数来初始化状态,从而解决这个错误。

代码语言:javascript复制
import {useState} from 'react';

export default function App() {
  const [counter, setCounter] = useState(() => 100   100);

  return (
    <div>
      <h1>Count: {counter}</h1>
    </div>
  );
}

我们向useState方法传递了一个函数。这个函数只会在组件第一次渲染时被调用,并且会计算出初始状态。你也可以直接向useState方法传递一个初始值。

另外,你也可以像前面的例子那样使用一个条件或事件处理器。

代码语言:javascript复制
import {useState} from 'react';

export default function App() {
  const [counter, setCounter] = useState(0);

  // 


	

0 人点赞