3 种导致 React 无限循环的方式

本文介绍了在React中导致无限循环的三种常见方式:在render方法内更新状态、在useEffect中循环更新状态及不当配置事件处理器。同时提供了相应的解决办法。

原文:3 ways to cause an infinite loop in React

https://alexsidorenko.com/blog/react-infinite-loop/

React 中 3 种导致无限循环的方式

July 05, 2021

你有没有花时间尝试调试一个React 里的无限循环? 也许在这个过程中浏览器挂了几次,或者你遇到过如下的错误信息👇

Uncaught Error: Too many re-renders.
React limits the number of renders
to prevent an infinite loop.

以下是 React 中无限循环的 3 个潜在原因。

I. Updating the state inside the render

function App() {
  const [count, setCount] = useState(0);

  setCount(1); // infinite loop

  return ...
}

如果你直接在render方法或函数式组件的主体内更新状态,就会导致无限循环。

State updates → triggers re-render → state updates → triggers re-render → …

修正 🎉

你只想在组件挂载(mount)时更新一次状态吗? 使用以空数组作为依赖项的useEffect.

function App() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setCount(1);
  }, [])
  
  return ...
}

II. useEffect 里的无限循环

function App() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setCount(count + 1) // infinite loop
  }, [count])

  return ...
}

如果你在 useEffect 内不断更新状态,并设置被更新的属性为 useEffect 的依赖项,将导致无限循环。

count updates → useEffect detects updated dependency → count updates → useEffect detects updated dependency → …

修正 🎉

如果要根据之前的值更新状态,请使用函数式更新。 这样,你可以从依赖列表中删除 state 属性从而避免无限循环。

function App() {
  const [count, setCount] = useState(0);

  useEffect(() => {
    setCount(previousCount => previousCount + 1)
  }, [])

  return ...
}

III. 不正确地设置 event handler

export default function App() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={setCount(1)}>Submit</button> // infinite loop
  );
}

这不是设置 event handler 的正确方法,你需要向 onClick 提供一个函数,而非函数执行的结果。 通过在设置 event handler 之前就执行函数,render 内部的状态将被更新,这会导致无限循环。

State updates → triggers re-render → state updates → triggers re-render → …

修正 🎉

onClick 事件设置一个函数, 这是设置 event handler 的正确方法。 这样,状态只会在单击按钮后更新,不会导致无限循环。

export default function App() {
  const [count, setCount] = useState(0);

  return (
    <button onClick={() => setCount(1)}>Submit</button> // infinite loop
  );
}

如何发现无限循环

每次更新状态时,请想象更新后将发生的事件序列。 如果没有额外的用户交互,这个事件序列会导致你回到相同的状态更新,你可能有一个无限循环。

评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值