那么...Redux的action dispatch是同步还是异步的?(不使用thunk或saga)

5

我有些困惑当我分发redux操作时的行为。

示例:

onPressAdd() {
    this.props.addFloor({
        name: this.state.floor_name,
    });
    console.log(this.props.floors);
}

我正在调用redux的addFloor动作,它会将楼层添加到存储中的数组中,然后我使用console.log输出该变量,并期望更新状态([{name:'whatever'}]),但我得到了一个空数组[]

示例2:

async onPressAdd() {
    await this.props.addFloor({
        name: this.state.floor_name,
    });
    console.log(this.props.floors);
}

在这个例子中,我得到了一个完美更新的store:[{name:'whatever'}] 我无处不在地阅读“如果没有thunk或saga,则Redux actions dispatch是同步的(直接方式:dispatch action->reduce->store)”,但这证明dispatch是异步的。
那么真相在哪里?

异步!因为没有“thunk”就无法工作。 - Praveen Kumar Purushothaman
我没有使用thunks :D 我只是在store中进行状态更新 :D - Baterka
2
操作是同步的(这就是为什么需要 thunk 和类似的东西)。问题在于,尽管 actions 是同步的,但 React 的响应系统却不是。当您调用 console.log 时,React 尚未完成内部更新... - Dupocas
2个回答

7

单纯的派发操作是100%同步的。

这是一个Redux store的精简实现:

function createStore(reducer) {
    var state;
    var listeners = []

    function getState() {
        return state
    }

    function subscribe(listener) {
        listeners.push(listener)
        return function unsubscribe() {
            var index = listeners.indexOf(listener)
            listeners.splice(index, 1)
        }
    }

    function dispatch(action) {
        state = reducer(state, action)
        listeners.forEach(listener => listener())
    }

    dispatch({})

    return { dispatch, subscribe, getState }
}

dispatch()函数返回时,store会执行你的reducer函数,并调用所有store订阅者的回调函数。

只有在向store添加middleware时,dispatch过程才可能被中断,因为任何middleware都可以延迟、停止或重写已经被dispatch的任何action。

这个例子实际上是基于React工作原理的。在该点击事件处理程序内部,React尚未重新渲染和更新组件的props,因此this.props.whatever在dispatch前后仍然相同。


好的,所以当我需要在存储更新后执行操作时,“示例 2”是正确的实现。 - Baterka
1
两个例子都是正确的。你不必等待dispatch()完成 - 只需在dispatch()后的下一行做其他事情即可。 - markerikson

2
重要的是要意识到,在调用处理程序作为宏任务执行完成之前,React 不会更新组件的 props。因此,在 dispatch 之后的 console.log 中,props 尚未更新。
简单地说,做 Example 2,你只需将其拆分并在 await 行之后得到一个包含所有内容的新微任务,该微任务将在更新 props 后执行。
如果没有 async/await,使用 Promise.resolve(this.props.addFloor(...)).then(() => console.log(this.props.floors)) 也会产生相同的结果。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接