簡體   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