【问题标题】:ReactJS not passing updated StateReactJS 没有通过更新的状态
【发布时间】:2020-11-05 09:02:43
【问题描述】:

所以我是 React 的新手,我正在尝试将使用 axios 获取后的数据传递给组件:

index.js

class App extends React.Component {
  state = { pokemon: null, errorMsg: '' };
  componentDidMount() {
    api
      .get('', {
        params: {
          limit: 50,
          offset: showrandom(),
        },
      })
      .then((res) => {
        const temporary = res.data.results;
        const details = { pokemon: [] };
        temporary.forEach((e) => {
          api
            .get('/' + e.name)
            .then((res) => details.pokemon.push(res.data))
            .catch((e) => console.log(e));
        });
        this.setState({ pokemon: details.pokemon });
      })
      .catch((e) => this.setState({ errorMsg: e }));
  }
  render() {
    if (this.state.pokemon) {
      return (
        <React.Fragment>
          <div
            className="container-fluid"
            style={{ textAlign: 'center', justifyContent: 'center', marginBottom: '5em' }}
          >
            <img alt="logo" src="logo" />
            <p>by: Ihsan Fajar Ramadhan</p>
          </div>
          <div className="ui five column grid" style={{ padding: '2em' }}>
            <Cards data={this.state.pokemon} />
          </div>
        </React.Fragment>
      );
    } else {
      return (
        <React.Fragment>
          <div className="ui" style={{ textAlign: 'center', justifyContent: 'center', marginBottom: '5em' }}>
            <img alt="logo" src="logo" />
            <p>by: Ihsan Fajar Ramadhan</p>
          </div>
          <div className="ui" style={{ textAlign: 'center', justifyContent: 'center' }}>
            <i className="compass loading icon massive blue"></i>
            <p className="ui text blue">Loading...</p>
          </div>
        </React.Fragment>
      );
    }
  }
}

Card.js

import React from 'react';

const Card = (props) => {
  let pokemon = props.data.map((pokemon, i) => {
    return (
      <div className="column" key={i}>
        <div className="ui fluid card">
          <a className="image" href="/">
            <img alt="nama" src={pokemon.sprites.front_default} />
          </a>
          <div className="content" style={{ textAlign: 'center' }}>
            <a className="header" href="/">
              {pokemon.species.name}{' '}
            </a>
          </div>
        </div>
      </div>
    );
  });
  if (props.data.length > 0) {
    return <>{pokemon}</>;
  } else {
    return <>fetching</>;
  }
};

export default Card;

加载屏幕渲染成功,在pokemon状态更新后,它通过if(this.state.pokemon)这意味着状态已更新的条件,然后它尝试用组件渲染元素。但问题是组件的数据道具尚未传递,它呈现“获取”而不是{pokemon}。我一直在寻找解决方案,但我被困住了。奇怪的是,当我更改内容(添加或删除单词)时,数据会传递给组件。

【问题讨论】:

  • 您是否在 Card.js 组件中登录了props.data?它的结构是否正确,你能很好地看到日志吗?
  • 我很确定您所描述的情况是this.state.pokemon 是一个空数组。 [] 是真实的,但它的长度是 0,这是导致 fetching 被渲染的确切条件。你能显示你加载数据并调用 setState 的部分吗?
  • 我已经更新了这段代码,并且我已经 cosoled this.state.pokemon 它返回了口袋妖怪列表,Card.js 中的 console.log 的结果也返回了相同的数据。 this.state.pokemon 的初始值为 null,所以当它更新时应该渲染 元素。
  • 问题是:forEach 循环不会等待内部的异步代码,只有 for 循环会,而且您甚至没有使用过 await。当您调用this.setState({ pokemon: details.pokemon }); 时,所有的api 调用都还没有完成,它仍然是[],这正是导致您观察到的行为的原因。
  • 为了解决这个问题,你也可以使用Promise.all()并行运行所有请求,然后在.then回调中调用setState。进行调试的一种非常简单的方法是插入&lt;pre&gt;{JSON.stringify(this.state)}&lt;/pre&gt;,这样您将看到this.state 的实际内容,而不是可能无法反映其中实际内容的console.log 输出。

标签: javascript reactjs axios


【解决方案1】:

首先,感谢 Chris G 在评论中的提示。

问题是:forEach 循环不会等待内部的异步代码,只有 for 循环会这样做,而且您甚至没有使用 await。当你调用 this.setState({ pokemon: details.pokemon }); 时,所有的 api 调用都还没有完成,它仍然是 [],这正是导致你观察到的行为的原因。

所以这是我的解决方案:

  async loadApi(){
    const temp= await api.get('',{
      params:{
        limit:50,
        offset:showrandom()
      }
    });
    const pokemon=[];
    for(let i=0; i<temp.data.results.length; i++){
      await api.get('/'+temp.data.results[i].name)
      .then(res => pokemon.push(res.data))
    }
    this.setState({pokemon:pokemon});
    return pokemon;
  }
  componentDidMount(){
    this.loadApi();
  }

【讨论】:

    猜你喜欢
    • 2017-09-05
    • 2016-11-27
    • 1970-01-01
    • 1970-01-01
    • 2016-10-14
    • 1970-01-01
    • 2021-07-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多