在React渲染之前等待多个异步调用完成

问题描述 投票:3回答:3

我有一个组件,它依赖于在呈现内容之前异步检索数据。如果数据尚不可用,则渲染函数将返回Loader组件:

    if (this.state.loading) {
        return <Loader />;
    }

调用返回数据后,加载状态设置为false:

componentDidMount() {

        ExternalComponent.fetchData().then(response => {
            this.setState({
                loading: false,
                data: response
            });
        });
}

这工作正常,但如果我想并行添加另一个异步提取调用怎么办?在将“loading”状态设置为false之前,我如何才能正确等待两者完成?

reactjs react-redux
3个回答
5
投票

使用Promise.all

componentDidMount() {
  const fetchData1 = ExternalComponent.fetchData()
  const fetchData2 = AnotherExternalComponent.fetchData()

  Promise.all([ fetchData1, fetchData2 ]).then((responses) => {
      this.setState({
          loading: false,
          data: responses[0]
      });
  });
}

2
投票

我认为你有多个选项,但如果你已经使用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)那样显示加载组件。


0
投票

为了简单起见,您可以有两个或更多加载标志,如下所示:

if (this.state.loading1 || this.state.loading2) {
    return <Loader />;
}
© www.soinside.com 2019 - 2024. All rights reserved.