首页 > 解决方案 > 有没有办法为 foreach 的每次迭代设置状态

问题描述

我正在使用 React 应用程序中的 API,并且我试图让 API 调用作为一个承诺返回。

我正在使用效果很好的 Promise.all() 方法。

我一直在尝试将两个 API 调用的结果设置为使用它们自己的名称。承诺代码工作正常,我正在尝试对两组数据进行 forEach() 或 map() 并将它们保存为具有自己名称的状态。

我确信有一个简单的解决方案,但我已经为此挠头太久了!

我尝试在所有文档中搜索 .map 和 .forEach ,但没有成功!

fetchData(){
this.setState({loading: true})
const urls = ['https://api.spacexdata.com/v3/launches/past', 'https://api.spacexdata.com/v3/launches']

let requests = urls.map(url => fetch(url));
Promise.all(requests)
  .then(responses => {
    return responses
  })
  .then(responses => Promise.all(responses.map(r => r.json())))
  .then(launches => launches.forEach(obj => {
    // I need to set both values to state here
  }))
  .then(() => this.setState({loading: false}))
  }

API 调用返回两个不同的数组。我需要将两个数组分别设置为 State 并使用它们自己的名称。这可能吗?

标签: javascriptreactjsforeach

解决方案


如果我正确理解您的问题,更好的方法可能是完全避免迭代(即使用forEach()等)。相反,考虑一种基于“解构语法”的方法,看到数组中有已知/固定数量的项目,这些项目是从先前的承诺中解决的。

您可以通过以下方式使用此语法:

/* 
   The destructing syntax here assigns the first and second element of
   the input array to local variables 'responseFromFirstRequest'
   and 'responseFromSecondRequest' 
*/
.then(([responseFromFirstRequest, responseFromSecondRequest]) => {

      // Set different parts of state based on individual responses
      // Not suggesting you do this via two calls to setState() but
      // am doing so to explicitly illustrate the solution

      this.setState({ stateForFirstRequest : responseFromFirstRequest });
      this.setState({ stateForSecondRequest : responseFromSecondRequest });

      return responses
    })

因此,集成到您现有的逻辑中,它看起来像这样:

fetchData() {
  this.setState({
    loading: true
  })
  
  const urls = ['https://api.spacexdata.com/v3/launches/past', 'https://api.spacexdata.com/v3/launches']

  const requests = urls.map(url => fetch(url));
  
  Promise.all(requests)
    .then(responses => Promise.all(responses.map(r => r.json())))
    .then(([responseFromFirstRequest, responseFromSecondRequest]) => {
    
      this.setState({ stateForFirstRequest : responseFromFirstRequest });
      this.setState({ stateForSecondRequest : responseFromSecondRequest });
    
      return responses
    })
    .then(() => this.setState({
      loading: false
    }))
}


推荐阅读