首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >异步数据加载

异步数据加载
EN

Stack Overflow用户
提问于 2018-09-23 19:19:10
回答 2查看 1.2K关注 0票数 0

我正在从API下载数据并写入state (posts)

let res = await response.json();后的条件将在此函数之前执行。

他应该在什么时候执行this.setState({posts: res})

目前,这是不适当的,因为:

  • 我正在从带有嵌套对象列表的bug中获得一个大型对象。
  • 要调用render(),对象必须已经存在于state
  • 我无法在state中定义一个空对象,因为它太复杂了

功能:

代码语言:javascript
复制
async loadData()
{
    try
    {
        this.setState({ loading: true});

        let response = await fetch('http://localhost:5000/api/posts/', {
            method: 'GET',
            headers:
            {
                'Accept': 'application/json',
                'Content-Type': 'application/json'
            }
        });

        let res = await response.json();

        if (response.status >= 200 && response.status < 300)
        {
            console.log(res);

            this.setState({ posts: res});
            this.setState({ loading: false});
        }
        else
        {
            let error = res;
            throw error;
        }

    }
    catch (error)
    {
        console.log('error' + error)
    }
}
EN

回答 2

Stack Overflow用户

发布于 2018-09-23 19:32:50

只要用承诺

代码语言:javascript
复制
loadData() {
  this.setState({
    loading: true
  });

  fetch('http://localhost:5000/api/posts/', {
    method: 'GET',
    headers: {
      'Accept': 'application/json',
      'Content-Type': 'application/json'
    }
  }).then(response => response.json()).then(res => {
    this.setState({
      posts: res
    });
  }).catch(reason => {
    console.log('error ' + reason);
  }).finally(() => {
    this.setState({
      loading: false
    });
  });
}
票数 0
EN

Stack Overflow用户

发布于 2018-09-23 21:47:16

在当前的示例中,绝对没有理由使用async/await。我猜您相信,通过使用await,组件将只在完整的loadData函数完成时才呈现,但这是不正确的,因为async意味着将返回一个承诺。

您正在做的另一个假设是,只要您的数据尚未添加到您的状态中,您就不能render任何东西(您提到了调用呈现,但是这是通过自身反应来调用的,因此您不需要担心它,因为它是组件生命周期的一部分)

我创建了一个关于如何加载数据的小示例,基于您的代码,并有尽可能多的注释;)

代码语言:javascript
复制
const { Component } = React;

// only shows the breeds and potential subbreeds
const Breed = ({ name, subBreeds }) => {
  return (
    <div className="breed-item">
      <span className="breed-title">{ name }</span>
      { subBreeds && subBreeds.map( (sub, i) => <Breed key={i} name={sub} /> ) }
    </div>
  );
};

class BreedContainer extends Component {
  constructor() {
    super();
    // i'll be loading from the start
    this.state = { loading: true };
  }
  componentDidMount() {
    // flag to make sure I don't update my state when I am no longer mounted
    this.mounted = true;
    // get's called when my component will be added to the dom
    fetch('https://dog.ceo/api/breeds/list/all')
      // return the json
      .then( response => response.json() )
      // error occured with parsing the json, handle it
      // through the console, and return an empty object
      .catch( error => console.error( error ) || {} )
      // set the state (in case still mounted)
      .then( result => this.mounted && this.setState({
        loading: false,
        breeds: result.message
      }) );
  }
  componentWillUnmount() {
    // unmounted, make sure I do not update the state after that
    this.mounted = false;
  }
  render() {
    const { breeds, loading } = this.state;
    // loading, so just display a loading message
    if (loading) {
      return <div>Loading please wait</div>;
    }
    // no breeds available, an error might have occured
    // the user would have to check the console to make sure
    // or you could save the error message instead
    if (!breeds) {
      return <div>No dog breeds found</div>;
    }
    // show all the retrieved breeds
    return (
      <div className="breed-container">
        { Object.keys( breeds ).map( (breed, i) => <Breed name={breed} subBreeds={breeds[breed]} key={i} /> ) }
      </div>
    );
  }
}

const target = document.querySelector('#container');
ReactDOM.render( <BreedContainer />, target );
代码语言:javascript
复制
.breed-item {
  font-size: 0.95em;
  padding: 5px;
}
.breed-item > .breed-item {
  border-left: solid #a0a0a0 1px;
  margin: 3px;
  border-radius: 50%;
}
.breed-title {
  text-transform: capitalize;
}
代码语言:javascript
复制
<script id="react" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.6.2/react.js"></script>
<script id="react-dom" src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/15.6.2/react-dom.js"></script>
<div id="container"></div>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/52469460

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档