对数组使用 setState 时的无限循环
Posted
技术标签:
【中文标题】对数组使用 setState 时的无限循环【英文标题】:Infinite Loop when using setState for array 【发布时间】:2021-02-13 03:12:35 【问题描述】:我想在一个数组中存储 4 个“hi”。而不是:
strArr.push('hi');
strArr.push('hi');
strArr.push('hi');
strArr.push('hi');
我这样做了:
for(let i = 0; i<4; i++)
setStrArr([...strArr, "hi"])
但是,我收到此错误:错误:重新渲染过多。 React 限制渲染次数以防止无限循环
我不知道出了什么问题,我想知道当 i=3 时它是否没有达到。所以我做了一个检查:
for(let i = 0; i<4; i++)
setStrArr([...strArr, "hi"])
if(i==3)
console.log("done")
'i'的值确实达到了3,但是为什么我的代码又运行了?
这是我的代码:
function MyApp()
const [strArr, setStrArr] = useState([]);
for(let i = 0; i<4; i++)
setStrArr([...strArr, "hi"])
if(i==3)
console.log("done")
return(
<div>
</div>
)
【问题讨论】:
你在 JSX 的什么地方做这个 for 循环?你在用钩子吗?钩子的依赖是什么? @Amir-Mousavi 添加了我的代码 【参考方案1】:添加到其他答案,因为您正在执行 同步 代码,我将使用 useLayoutEffect 挂钩。 useLayoutEffect 运行,React 等待它完成。这对于响应等待来说很好,因为代码都是同步的,并且它可以防止您的组件在屏幕上“闪烁”,因为在渲染完成后会调用 useEffect。
function MyApp()
const [strArr, setStrArr] = useState([]);
useLayoutEffect(() =>
let fourHiArray = [];
for(let i = 0; i<4; i++)
fourHiArray = ([...fourHiArray, "hi"])
if(i==3)
console.log("done")
setStrArr(fourHiArray);
, []);
return(
<div>
</div>
)
【讨论】:
非常感谢。我之前还没有使用过useLayoutEffect
,将阅读它【参考方案2】:
在重新渲染时调用整个函数 MyApp,因此在每次重新渲染时,您的循环都会重新开始。如果您只想调用一次,请在 useEffect 中调用它。像这样
useEffect(() => *your code here*, []
使用空数组作为第二个参数的 useEffect 仅在第一次渲染时调用。
如果你想设置你的初始状态,我建议你在 useState(['hi','hi','hi','hi'])
【讨论】:
【参考方案3】:我相信您可能会遇到问题,因为调用 setStringArray
是一种“副作用”。
这将导致函数组件无限重新渲染,因为钩子已经更新了组件的状态,导致重新渲染,然后无限更新状态。
基本上,您不应该尝试在同一行中同时读取和更新strArray
。
您应该只在完全填充数组后调用setStrArr
一次。
我认为您还应该考虑使用 useEffect
钩子来实现这样的行为。
它传递的最后一个参数告诉 React 仅在给定的参数(在本例中为 strArray
)发生更改时才运行此 useEffect
挂钩内的代码。
当您希望在您的组件中具有“副作用”时,此钩子设计。
所以也许你可以尝试一些类似的方法来防止你的无限重新渲染:
function MyApp()
const [strArr, setStrArr] = useState([]);
useEffect(() =>
const fourHiArray = [];
for(let i = 0; i<4; i++)
fourHiArray = ([...fourHiArray, "hi"])
if(i==3)
console.log("done")
setStrArr(fourHiArray);
, [strArr]);
return(
<div>
</div>
)
【讨论】:
谢谢。但是你能否进一步解释一下为什么改变状态会导致重新渲染?一直以来,我认为只有使用像useEffect
这样的钩子才会导致无限地重新渲染。
别担心!希望这可以帮助。因此,当状态更新时,React 组件将总是重新渲染!这是一个“这就是 React 是如何工作的”的案例。这里有一篇很酷的博客文章:lucybain.com/blog/2017/react-js-when-to-rerender/…。以上是关于对数组使用 setState 时的无限循环的主要内容,如果未能解决你的问题,请参考以下文章
在 componentWillUpdate 或 componentDidUpdate 中重复调用 setState。 React 限制嵌套更新的数量以防止无限循环