如果将第二个参数作为数组传递并放入空对象,那么为什么useEffect会产生无限循环



我有一个带有API过滤器参数的对象,我将此对象传递给useEffect。

let dataForFilter = typeof defaultFormData[someKey] !== 'undefined'
? defaultFormData[someKey]
: {};
for (let key in props.route.params) {
if (props.route.params.hasOwnProperty(key)) {
dataForFilter[key] = props.route.params[key];
}
}
useEffect(() => {
async function fetchData() {
const body = {
...dataForFilter,
};
loadData(url, body);
}
fetchData();
}, [dataForFilter]);

默认情况下,对象是空的,但如果我将数组中的空对象作为第二个参数传递,则会产生无限循环。我不明白为什么?请有人解释一下为什么以及如何解决这个问题。

每次运行函数时,都会在此处创建一个新的空对象:

let dataForFilter = typeof defaultFormData[someKey] !== 'undefined'
? defaultFormData[someKey]
: {};

因此,如果defaultFormData[someKey]不存在,则依赖数组的值在每次渲染时都会发生变化。空对象不等于它自己。

console.log([{}] === [{}]);
console.log({} === {});

改为在函数外部创建对象,以便其引用稳定。

const emptyObj = {};
const MyComponent = ({ defaultFormData }) => {
// ...
let dataForFilter = typeof defaultFormData[someKey] !== 'undefined'
? defaultFormData[someKey]
: emptyObj;

在useEffect中,调用一个函数来重新发布组件。在useEffect依赖项(末尾的数组(中,您将dataForFilter作为依赖项传递。这意味着,每当dataForFilter发生更改时,就会再次调用useEffect。但是,由于useEffect使组件重新呈现,并且dataForFilter没有被定义为状态,而是被定义为组件内部的正常变量,因此它将再次用另一个值定义(注意:即使是具有相同值的对象也不是以前的对象(。如果您希望任何useEffect在组件渲染时被调用一次,请将一个空数组作为依赖项传递,如下所示:

let dataForFilter = typeof defaultFormData[someKey] !== 'undefined' // <-- dataForFilter gets evaluated again and changes its value, which calls the useEffect
? defaultFormData[someKey]
: {};
for (let key in props.route.params) {
if (props.route.params.hasOwnProperty(key)) {
dataForFilter[key] = props.route.params[key];
}
}
useEffect(() => {
async function fetchData() {
const body = {
...dataForFilter,
};
loadData(url, body); // <-- You rerender the component somewhere in this function, dataForFilter gets defined again and is another object (with the same value BUT still another object)
}
fetchData();
}, []); // <-- Empty array as dependency, only gets called once

最新更新