同步Redux操作

时间:2017-09-29 17:32:34

标签: redux react-redux redux-thunk

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

第一个操作发生并且状态正确更改,但看起来在此之后不会立即触及反应前端组件,但它会转到第二个调度。当我在第一次发送后添加一个短timeout时,它可以工作,但我讨厌硬编码一个固定的等待时间。

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

不工作:

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

WORKING:

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

1 个答案:

答案 0 :(得分:1)

您所谓的同步操作实际上异步操作,在特定时间更新商店。像这样的事情的一般模式是对行动的每个状态进行(至少)三次调度。

  1. 启动异步操作
  2. 异步操作成功
  3. 异步操作失败
  4. 启动异步操作会调度“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
            );
    };