反应useEffect无限循环 [英] React useEffect infinite loop

查看:256
本文介绍了反应useEffect无限循环的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在对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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆