首页 > 解决方案 > React Redux - 在调度下一个操作之前等待异步 api 调用完成

问题描述

我正在开发一个使用 React + Redux 的 Web 应用程序,后端使用 Django (DRF)。我正在使用 axios 发送我的 API 请求,这是异步的。我现在面临的问题是分派的操作在分派下一个操作之前不会等待 API 调用完成。下面是我的代码

const mapDispatchToProps = dispatch => ({
    success: id => {
        dispatch(fetchSalesProject(id));
        dispatch(createMessage('Requirement successfully updated!'))
    }
})

fetchSalesProject action(axiosInstance只是对axios调用的自定义修改,功能是一样的)

export const fetchSalesProject = (id) => (dispatch) => {
    console.log('enter sales project action')
    axiosInstance
        .get(`/sales-project/detail/${id}/`)
        .then((res) => {
            console.log('fetched data')
            dispatch({
                type: FETCH_SALES_PROJECT,
                payload: res.data,
            });
        })
        .catch((err) => dispatch(returnErrors(err.response.data, err.response.status)));
};

createMessage 操作

export const createMessage = (message) => {
  console.log('message')
  return {
    type: CREATE_MESSAGE,
    message: message,
  };
};

调用this.props.success(参考mapDispatchToProps)时,在接收到api调用响应数据之前显示消息(从console.log('message')在console.log('fetched data')之前运行的事实就可以看出) )

我希望在运行 createMessage 操作之前从 api 调用中获取数据,是否有关于如何完成此操作的建议?我是 React 的新手,尤其是 Redux,所以希望你们可以为我指明正确的方向来实现这一点。

另外,我是否可以检查在 mapDispatchToProps 中进行调度以及在操作中进行调度是否错误(请参阅 fetchSalesProject 操作)。它会导致任何性能问题,还是不赞成这样做?请告诉我,因为我对 Redux 很困惑。

感谢大家通读,感谢所有帮助:-)

标签: reactjsreduxreact-redux

解决方案


当您从 UI 调度时,您只需向 reducer 发送一个对象,该对象反过来会修改 store 的状态,并在流程结束时重新渲染引用已更改道具的组件。在您调度第一个动作的那一刻,没有任何东西告诉组件它应该在将下一个对象发送到减速器之前等待

所以你有2个选择,

第一个是在 UI 本身使用componentDidUpdateuseEffect在第一个动作减少后运行第二个动作


 componentDidUpdate(prevProps) {
       if (prevProps.salesProject != this.props.salesProject)
         dispatch(createMessage('Requirement successfully updated!'))
      }

虽然我假设dispatch(fetchSalesProject(id));修改salesProject道具

另一种方法是,如果你真的很好,message并且salesProject会聚集到减速器,是在一个动作中调度它们


 export const fetchSalesProjectAndMessage = (id, message) => (dispatch) => {
  console.log('enter sales project action')
  axiosInstance
    .get(`/sales-project/detail/${id}/`)
    .then((res) => {
        console.log('fetched data')
        dispatch({
            type: FETCH_SALES_PROJECT_AND_MESSAGE,
            payload: { data: res.data, message }
        });
    })
    .catch((err) => dispatch(returnErrors(err.response.data, err.response.status)));
 };

在 reducerpayload.data中,要么payload.message参考所需的信息


推荐阅读