同步 Redux 动作

Synchronous Redux Actions

我正在尝试在 Redux 中进行同步调度调用,其中第一个调用会更新 isLoading 状态,以便我们可以在 UI 上显示一个加载图标,然后第二个调用会执行很多操作更新项目位置的幕后同步计算 - 大约需要 2-5 秒。

第一个动作发生并且状态被正确更改,但似乎紧随其后它没有击中 React 前端组件,而是进入了第二个调度。当我在第一次调度后添加一个简短的 timeout 时它会起作用,但我讨厌硬编码一个固定的等待时间。

这个问题有更好的解决方案吗?

不工作:

const showLoadingIcon = () => ({type: types.SHOW_LOADING_ICON});
export const updateInteractionTypeScores = (updatedValues) => dispatch => {
    dispatch(showLoadingIcon());
    dispatch({type: types.UPDATE_VALUES, updatedValues});
};

正在工作:

const showLoadingIcon = () => ({type: types.SHOW_LOADING_ICON});
export const updateInteractionTypeScores = (updatedValues) => dispatch => {
    dispatch(showLoadingIcon());
    setTimeout(() => dispatch({type: types.UPDATE_VALUES, updatedValues}), 100);
};

您所谓的同步操作实际上异步操作,在特定时间更新商店。此类事情的一般模式是(至少)为每个动作状态分配三个调度。

  1. 异步操作已启动
  2. 异步操作成功
  3. 异步操作失败

启动异步操作会分派一个 "ASYNC_ACTION_LAUNCHED" 操作,该操作会更新您的组件正确连接到的商店(对吗?)因此会显示加载图标。

成功后,调度 "ASYNC_ACTION_SUCCESS",更新商店,组件重新呈现新的商店内容。

失败时,调度 "ASYNC_ACTION_FAILURE",更新存储,组件重新呈现空内容和错误消息。

在实践中,这相当于更多的代码,但这允许更多的可能性:

const asyncActionLaunched = () => ({type: types.ASYNC_ACTION_STARTED});
const asyncActionSuccess = () => ({type: types.ASYNC_ACTION_SUCCESS});
const asyncActionFailed = () => ({type: types.ASYNC_ACTION_FAILED});

export const updateInteractionTypes = dispatch => {
    dispatch(asyncActionLaunched());

    // I don't know your setup
    // But this whould either be a Promise, or return a boolean

    // in the case of a synchronous function
    const result = makeSynchronousCalculations();
    if (result) {
        dispatch(asyncActionSuccess());
        // dispatch another action that updates store
    } else {
        dispatch(asyncActionFailed());
        // dispatch another action that updates store
    }
    // in the case of a promise
    asyncBlockingAction()
        .then(
            dispatch(asyncActionSuccess());
            // dispatch another action that updates store
        ).catch(
            dispatch(asyncActionFailed());
            // dispatch another action that updates store
        );
};