[英]React useEffect infinite loop
I was experimenting with React a little and wanted to retrieve a json file I had on S3 bucket.我对 React 进行了一些试验,并想检索我在 S3 存储桶上的 json 文件。 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>
);
}
In the begining I was getting the error that when using setPicList
, picList
doesn't take the value of json file.一开始我收到错误,即在使用
setPicList
, picList
不采用 json 文件的值。 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 []
.我正在使用
console.log()
进行调试,因此我确定Storage.get
正在获取正确的 url, fetch()
正在获取文件 json,但picList
打印默认值[]
。
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
的值得到了正确的值(但它不断为我认为的每个渲染获取 S3)。
I was following this guide我正在遵循本指南
Edit: for completeness, picList
is not getting updated if I remove the dependency, ie if I let []
instead of [picList]
.编辑:为了完整
picList
如果我删除依赖项,即如果我让[]
而不是[picList]
,则picList
不会更新。
As Brian mentioned before, your useEffect is set to trigger whenever picList is changed.正如 Brian 之前提到的,您的 useEffect 设置为在 picList 更改时触发。 Since picList is being changed inside useEffect, this creates an infinite loop.
由于 picList 在 useEffect 中被改变,这就造成了一个无限循环。
Since you're retrieving an object from S3, all you need to do is retrieve it once.由于您正在从 S3 检索对象,因此您需要做的就是检索它一次。
useEffect(() => {
...
}, []);
Ensures that the useEffect will only run once, when first rendered确保 useEffect 在第一次渲染时只运行一次
React hooks changes states asynchronously, so console.logging right after will produce either None or the previous value. React hooks 异步更改状态,因此之后的 console.logging 将生成 None 或先前的值。
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>
);
You call setPicList
in the callback function that listens for side effects off picList
:你在回调函数中调用
setPicList
来监听picList
副作用:
useEffect(() => {
setPicList(someValue); //infinite loop because this causes a side effect
}, [picList]);
You are listening for changes to picList
with useEffect
and than make changes to picList
when there is a change to picList
in your useEffect
call back function.您正在使用
useEffect
监听对picList
的更改, picList
在useEffect
回调函数中对picList
进行更改时对picList
进行更改。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.