当数据不改变时,请告诉我关于UseEffect Loop的信息



你好,我有这个组件,经过一些阅读,我已经明白,当数组中的数据发生变化时,会再次调用useEffect,但在我的情况下,这并没有改变,我进入了一个循环。

export default function Test() {

const [dates, setDates] = useState([]);
let values = [];
useEffect(() => {
getAllFilledJournauxDates().then(function(response) {
values = response;
setDates(values);
}
);
}
, [dates]);

console.log(values);


return(
<div>
{dates.map(date => {
return <div>{date}</div>
})}
</div>
);
}

[EDIT 2]添加getAllFilledJournauxDates()函数

export async function getAllFilledJournauxDates() {

let dates = [];
let journaux = getAllJournaux()
.then(response => {
Object.keys(response).forEach(element => {
dates.push(new Date(new Date(response[element].date)).getFullYear() + "-" + (new Date(response[element].date)).getMonth() + "-" + (new Date(response[element].date)).getDate());
})
})
return dates;
}

[编辑]

export default function Test() {

const [dates, setDates] = useState([]);
let values = [];
useEffect(() => {
console.log("useEffect"); // displayed two time in console
getAllFilledJournauxDates().then(function(response) {
values = response;
setDates(values);
console.log(values); //display the array of dates
}
);
}
, []);

console.log(values); // display an empty array


return(
<div>
{dates.map(date => {
return <div>{date}</div> // display nothing on screen
})}
</div>
);
}

就像@rowinbot建议的那样,我已经删除了数组中的变量,但屏幕上还没有任何东西,我可以看到变量填充在我的控制台上,并且useEffect看起来像他被调用了两次…我想补充的是,一开始我尝试用这些值填充日历,但没有得到我想要的结果,我已经渲染结果最简单

TL;DR:您应该从效果的依赖数组中删除dates

Effects(也就是我们传递给useEffect钩子的函数)在渲染后在React上运行,如果你想只运行效果,依赖数组充当运行效果的逃生舱口。

这里你说每当dates更新(它的值改变)你想运行效果,反过来调用setDates(...)和改变dates的值,这产生组件的渲染,因为dates改变了,效果再次运行,并且……

只要从依赖数组中删除dates,你应该没事:

useEffect(() => {
getAllFilledJournauxDates().then(function(response) {
values = response;
setDates(values);
}
);
}
, []);

记住保持依赖数组即使它空,这个基本上告诉反应只运行效果"once"(React 18的严格模式使这在开发中有所不同)并防止循环。

完全避免依赖数组(省略它)会导致相同的结果,一个无限循环,这告诉React在上每个渲染,你想要运行效果,这会导致另一个渲染…和循环永远

你可以在测试版React文档中阅读更多关于效果的内容,它很好地总结了它的语义。

你正在更新useEffect中的日期,这就是每次重新运行useEffect时你改变日期的方式,这会导致它再次重新运行并创建一个循环。尝试使用其他东西来触发useEffect,而不是日期。也许你可以试着把它放在改变"价值观"上;而不是日期和获取响应之外的useEffect,并把它放在值。

useEffect(() => {
setDates(values);
}
, [values]);

console.log(values);

最新更新