繁体   English   中英

从多个来源异步更新React状态

[英]Update React state asynchronously from multiple sources

我正在尝试使用immutability-helper从多个来源(API调用)异步更新我的React状态。 但是,在我看来,这不是走的路,因为状态始终仅使用来自单一来源的值进行更新。 有人可以解释我为什么会这样以及如何正确处理我的状态更新吗?

import React from 'react';
import update from 'immutability-helper';

class App extends React.Component {
  constructor(props, context) {
    super(props, context);
    this.state = {
      updateInterval: 60,  // in seconds
      apiEndpoints: [
        '/stats',
        '/common/stats',
        '/personal/stats',
        '/general_info',
      ],
      items: [
        { itemName: 'One', apiUrl: 'url1', stats: {} },
        { itemName: 'Two', apiUrl: 'url2', stats: {} },
      ],
    };
    this.fetchData = this.fetchData.bind(this);
  }

  componentDidMount() {
    this.fetchData();
    setInterval(() => this.fetchData(), this.state.updateInterval * 1000);
  }

  fetchData() {
    this.state.apiEndpoints.forEach(endpoint => {
      this.state.items.forEach((item, i) => {
        fetch(`${item.apiUrl}${endpoint}`)
          .then(r => r.json())
          .then(res => {
            // response from each endpoint contains different keys.
            // assign all keys to stats object and set default 0 to
            // those which don't exist in response
            const stats = {
              statsFromFirstEndpoint: res.first_endpoint ? res.first_endpoint : 0,
              statsFromSecondEndpoint: res.second_endpoint ? res.second_endpoint : 0,
              statsFromThirdEndpoint: res.third_endpoint ? res.third_endpoint : 0,
            };
            this.setState(update(this.state, {
              items: { [i]: { $merge: { stats } } }
            }));
          })
          .catch(e => { /* log error */ });
      });
    });
  }

  render() {
    return (
      <div className="App">
        Hiya!
      </div>
    );
  }
}

export default App;

您应该在setState使用prevState参数以确保其始终使用最新状态:

this.setState(prevState =>
  update(prevState, {
    items: { [i]: { $merge: { stats } } },
  }));

或者,将您的请求映射到一个promise数组,然后在所有这些promise解析后设置setState

const promises = this.state.apiEndpoints.map(endPoint =>
  Promise.all(this.state.items.map((item, i) =>
    fetch(), // add ur fetch code
  )));
Promise.all(promises).then(res => this.setState( /* update state */ ));

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM