我正在对React进行一些试验,并想检索我在S3存储桶中拥有的json文件。我正在使用下一个代码
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
打印出默认值[]
。
现在,使用上面的代码代替,我得到了一个无限循环,但是这次picList
的值得到了正确的值(但是我想为每个渲染都继续获取S3)。
我正在关注this guide
编辑:出于完整性考虑,如果删除依赖项,即picList
而不是[]
,[picList]
不会更新。
答案 0 :(得分:3)
如Brian所述,您的useEffect设置为在picList更改时触发。由于在useEffect中更改了picList,因此将创建一个无限循环。
由于您要从S3检索对象,因此您只需要做一次检索即可。
useEffect(() => {
...
}, []);
确保useEffect在首次呈现时仅运行一次
React钩子异步更改状态,因此,在console.logging之后立即生成None或前一个值。
您需要做的是在渲染函数中添加条件语句,以便在状态更新时重新渲染组件。
function renderLander() {
return (
<div className="lander">
<h1>Lander</h1>
</div>
);
}
return(
<div className="Gallery">
{picList ? renderLander() : null}
</div>
);
答案 1 :(得分:1)
您在回调函数中调用setPicList
,以监听picList
的副作用:
useEffect(() => {
setPicList(someValue); //infinite loop because this causes a side effect
}, [picList]);
您正在监听picList
对useEffect
的更改,而当picList
回调中picList
发生更改时,您将对useEffect
进行更改功能。