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

时间:2019-01-08 23:01:42

标签: javascript reactjs foreach

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

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

我一直试图将两个API调用的结果设置为使用自己的名称声明。 Promise代码运行正常,我正在尝试对两组数据进行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 :(得分:0)

如果我正确理解了您的问题,则更好的方法可能是完全避免迭代(即使用forEach()等)。相反,请考虑基于“ destructuring syntax”的方法,因为您看到数组中有已知/固定数量的项目,可以根据先前的承诺进行解决。

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

/* 
   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
    }))
}

答案 1 :(得分: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
    }, {})
}))

答案 2 :(得分: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()))