有没有一种方法可以为foreach的每个迭代设置状态?

3
我正在一个React应用程序中使用API,并尝试将API调用作为一个承诺返回。我使用的Promise.all()方法非常有效。但是,我卡在了尝试使用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,并赋予它们各自的名称。这是否可行?
3个回答

0
如果我正确理解了您的问题,更好的方法可能是完全避免迭代(即使用forEach()等)。相反,考虑一种基于“解构语法”的方法,因为您已经知道/固定了从前一个Promise解析出来的数组中的项目数量。
您可以按以下方式使用此语法:
/* 
   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
    }))
}


0

如果这两个数组在状态上不会相互干扰,那么在每次迭代中只调用setState是否有问题?

.then(launches => launches.forEach(obj => {
  this.setState({ [obj.name]: obj });
}))

如果您想要最小化更新的次数,那么您可以从这两个数组中创建一个对象,并将其扩展到一个调用的状态中。
.then(launches => this.setState({
    ...launches.reduce((obj, launch) => {
        obj[launch.name] = launch
        return obj
    }, {})
}))

0

forEach 还提供了索引作为第二个参数。这样做不好吗?

launches.forEach((obj, idx) => {
  if (idx === 0) {
    this.setState('first name', obj);
  } else if (idx === 1) {
    this.setState('second name', obj);
  }
})

另外,这一部分实际上什么也没有做。

  .then(responses => {
    return responses
  })

这里的Promise.all()也没有做任何事情。

.then(responses => Promise.all(responses.map(r => r.json())))

应该是

.then(responses => responses.map(r => r.json()))

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接