我想加载一堆涉及多个API的数据,我在foreach中做了setState,它工作但我认为设计是错误的,因为我看到我的屏幕上闪烁。
API.fetchMain().then(main => {
main.forEach(o => {
const main_id = o.main_id
this.setState({
main: o
})
API.fetchSub(main_id)
.then(sub => {
this.setState({
sub
})
API.fetchOthers(main_id, sub.id)
.then(others => {
this.setState({
others
})
})
})
})
}
我认为我应该使用promises来重构,我试过但我认为我的设计是错误的。
API.fetchMain().then(main => {
let promise = []
main.forEach(o => {
const main_id = o.main_id
this.setState({
main: o
})
promise.push(
API.fetchSub(main_id)
.then(sub => {
return API.fetchOthers(main_id, sub.id)
})
)
})
Promise.all(promise).then(resp => console.log('do setState here'))
}
需要帮助。
答案 0 :(得分:0)
在我看来,您正在获取一个资源,该资源为您提供有关如何进一步请求的信息。如果您愿意使用获取库,我建议axios。下面是我想象它的样子
import axios from 'axios'
fetch(){
// Make the initial request
var options = { url: "URL of main resource", method: "GET" }
axios(options).then(res => {
// Create an array of next requests from the response
var next_requests = res.data.main.map(id => axios.get(`${resource_url}/${id}`))
//Make the requests in parallel
axios.all(next_requests).then(axios.spread(() => {
//since we don't know how many request we can iterate
//over the arguments object and build the new state
var newState = {}
arguments.forEach(i => {
// how you want to structure the the state before setting it
})
this.setState(newState)
})
}).catch(err => //error handling logic here)
}
根据我对你的问题的理解,你也可以(因为你正在使用react)将你的获取请求分解为在挂载时被调用的组件。一个简单的例子:
const class MainComp extends Component {
constructor(props){
super(props)
this.state = {
main: []
}
}
componentDidMount(){ this.fetchMain() }
fetchMain() {
axios.get('url').then(res =>
this.setState({main_id: res.data.main.id})
}
sendSubFetchToParent(dataFromChild){
// Do what you need to with the data from the SubComp child
}
render(){
return (
{this.state.main.map(id => <SubComp id={id) afterFetch={this.sendSubFetchToParent}/>}
)
}
}
const class SubComp extends Component {
componentDidMount(){ this.fetchSub() }
fetchSub() {
//Pass the results to the parent after the fetch completes.
// You can add the usual error handling here as well.
axios.get('url').then(res => this.props.afterFetch(res.data))
}
render(){
//Return null or render another sub component for further nested requests
return null
}
}
在上面,MainComp发起请求。当它得到一个响应(在你的例子中是一个数组)时,我们将该响应设置为状态。这会触发重新渲染,它将安装n个SubComp。当这些安装时,他们将发起他们获取数据的请求。对于SubComp,我们从父级传递回调,因此SubComp可以将其获取响应发送回MainComp(并通过设置状态等来适当地处理它)。您可以在SubComp中返回null,或者让它挂载将进一步请求的组件。
通过这种方式,您的获取请求现在已组件化。