我有一个组件,它依赖于在呈现内容之前异步检索数据。如果数据尚不可用,则渲染函数将返回Loader组件:
if (this.state.loading) {
return <Loader />;
}
调用返回数据后,加载状态设置为false:
componentDidMount() {
ExternalComponent.fetchData().then(response => {
this.setState({
loading: false,
data: response
});
});
}
这工作正常,但如果我想并行添加另一个异步提取调用怎么办?在将“loading”状态设置为false之前,我如何才能正确等待两者完成?
使用Promise.all:
componentDidMount() {
const fetchData1 = ExternalComponent.fetchData()
const fetchData2 = AnotherExternalComponent.fetchData()
Promise.all([ fetchData1, fetchData2 ]).then((responses) => {
this.setState({
loading: false,
data: responses[0]
});
});
}
我认为你有多个选项,但如果你已经使用redux
,为什么不把你的逻辑移到那里?在redux-thunk
的帮助下,您可以在动作创建器中执行异步操作并使用全局进程状态。
相关减速机:
const initialState = 0;
const progressReducer = (state = initialState, action) => {
switch (action.type) {
case types.INCREMENT_PROGRESS:
return state + 1;
case types.DECREMENT_PROGRESS:
return Math.max(state - 1, 0);
default:
return state;
}
};
相关行动:
export const incrementProgress = () => ({ type: types.INCREMENT_PROGRESS });
export const decrementProgress = () => ({ type: types.DECREMENT_PROGRESS });
然后你的动作创建者将是这样的:
export const anAsyncFunction = () => async dispatch => {
dispatch(incrementProgress());
try {
const someResponse = await someAsyncJob();
dispatch(anAction(someResponse));
} catch (error) {
errorHandler(error);
} finally {
dispatch(decrementProgress());
}
};
这是异步函数的一个示例,但您当然可以使用promise。当您想要进行多个异步操作时,只需激活您的操作创建者,然后将该过程增加一个。在你的组件中,你将检查你的progress
状态是否大于0或者像if(progress)
那样显示加载组件。
为了简单起见,您可以有两个或更多加载标志,如下所示:
if (this.state.loading1 || this.state.loading2) {
return <Loader />;
}