英文:
Why will setting a state of a variable to a constant array variable cause an infinite loop with a useEffect?
问题
以下是翻译好的内容:
// 这段代码会产生一个无限循环,使渲染达到最大值。
// 我不确定为什么会发生这种情况。
// 在我们的企业代码库中也遇到了类似的问题,通过将常量数组更改为状态变量来解决,这样它就不会总是改变,并且将其从 useEffect 中移除,因为它不会改变。
// 我猜测通过将 y 这个不同的变量设置为一个常量数组,它会导致重新渲染,因为指针值发生了变化?
// 我不确定,但我觉得这种行为很奇怪。
import React, { Component, useState, useEffect, useCallback } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
const App = (props) => {
const [y, setY] = useState([]);
const x = [1001, 1002];
setY(x);
useEffect(() => {
console.log(x);
}, [x]);
return <div></div>;
};
render(<App appName="用户详情" />, document.getElementById('root'));
英文:
This code below produces an infinite loop, maxing out the rendering.
I'm unsure why this is happening.
We have a similar problem in our enterprise codebase that has been resolved by changing the constant array to a state variable so it doesn't always change and by removing it from the useEffect because it won't change.
I'm guessing that by setting y, a different variable, to a constant array, it causes a rerender and x changes because the pointer value changes?
I'm not sure but I find this behavior odd.
import React, { Component, useState, useEffect, useCallback } from 'react';
import { render } from 'react-dom';
import Hello from './Hello';
import './style.css';
const App = (props) => {
const [y, setY] = useState([]);
const x = [1001, 1002];
setY(x);
useEffect(() => {
console.log(x);
}, [x]);
return <div></div>;
};
render(<App appName="User Details" />, document.getElementById('root'));
答案1
得分: 2
事实与@Anubhav Raj所建议的完全相反。
每次组件重新渲染时,x都是一个全新的引用数组。而且你在没有任何包装的情况下调用了setY
(通常你会在useEffect
中调用这些setter,或者使用useCallback
创建一个回调,但在这种情况下无论如何,它都会在每次渲染时发生)。
可以这样想:
let x = [1, 2];
x = [1, 2];
这是两个不同的数组对象,尽管两者的元素相同。这在同一个函数的两次不同运行中发生,使得理解起来有些困难,但本质上发生了相同的事情。
因为你用这个新值调用了setY
,这会触发重新渲染,导致整个过程再次发生。
查看此文章获取更多信息。
英文:
The truth is exactly the opposite from what @Anubhav Raj suggests.
Each time your component renders, x is an entirely new array by reference. And you are calling setY
with it without any kind of wrapper (usually you'll call these setters in useEffect
or a callback you create with useCallback
, but in this case it doesn't matter because it will always happen on every render anyway).
Think of it this way:
let x = [1, 2];
x = [1, 2];
These are two different Array objects, even though the elements of both are the same. The fact that this is happening in two different runs of the same function makes it difficult to reason about, but essentially the same thing is happening.
Because you're calling setY
with that new value, that queues up a rerender, causing the whole process to happen again.
Check out this post for more info.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论