我正在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。这可能吗?
答案 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()))