反应useEffect无限循环 [英] React useEffect infinite loop
问题描述
我正在对React进行一些实验,想检索我在S3存储桶中拥有的json文件.我正在使用下一个代码
I was experimenting with React a little and wanted to retrieve a json file I had on S3 bucket. I'm using the next code
import React, { useState, useEffect } from "react";
import { Storage } from "aws-amplify";
export default function Gallery(props){
const [picList, setPicList] = useState([]);
useEffect(() => {
async function onLoad() {
try{
const picUrl = await Storage.get('list.json');
const picr = await fetch(picUrl);
const picjs = await picr.json();
setPicList(picjs);
console.log(picList);
}
catch(e){
alert(e);
}
};
onLoad();
}, [picList]);
function renderLander() {
return (
<div className="lander">
<h1>Lander</h1>
</div>
);
}
return(
<div className="Gallery">
{renderLander()}
</div>
);
}
在一开始,我得到一个错误,即使用setPicList
时,picList
不采用json文件的值.我正在使用console.log()
进行调试,因此我确定Storage.get
正在获取正确的url,fetch()
正在获取文件json,但是picList
打印默认值[]
.
In the begining I was getting the error that when using setPicList
, picList
doesn't take the value of json file. I'm using console.log()
to debug, so I'm sure that Storage.get
is getting the right url, fetch()
is getting the file json, but picList
prints the default value []
.
现在,用上面的代码代替,我得到了一个无限循环,但是这次picList
的值得到了正确的值(但我认为每次渲染都不断获取S3).
Now, with the code above instead I'm getting an infinite loop, but this time the value of picList
is getting the right value (but it keeps fetching S3 for every render I think).
我正在关注本指南
出于完整性考虑,如果删除依赖项,即如果让[]
代替[picList]
,则picList
不会得到更新.
for completeness, picList
is not getting updated if I remove the dependency, ie if I let []
instead of [picList]
.
推荐答案
如Brian所述,您的useEffect设置为在更改picList时触发.由于在useEffect中更改了picList,因此将创建一个无限循环.
As Brian mentioned before, your useEffect is set to trigger whenever picList is changed. Since picList is being changed inside useEffect, this creates an infinite loop.
由于您要从S3检索对象,因此您只需要做一次检索即可.
Since you're retrieving an object from S3, all you need to do is retrieve it once.
useEffect(() => {
...
}, []);
确保useEffect在首次呈现时仅运行一次
Ensures that the useEffect will only run once, when first rendered
React钩子异步更改状态,因此,在console.logging之后立即生成None或前一个值.
React hooks changes states asynchronously, so console.logging right after will produce either None or the previous value.
您需要做的是在渲染函数中添加条件语句,以便在状态更新时重新渲染组件.
What you need to do is add a conditional statement to your render function, to re-render the component when the state updates.
function renderLander() {
return (
<div className="lander">
<h1>Lander</h1>
</div>
);
}
return(
<div className="Gallery">
{picList ? renderLander() : null}
</div>
);
这篇关于反应useEffect无限循环的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!