Redux更新过程中触发渲染是否符合预期?同步性疑问
Redux更新是否为同步操作?该现象是否符合预期?
核心结论
Redux的核心更新流程(action触发、reducer执行、state更新)是同步的,但React组件的渲染时机由React的更新调度逻辑决定。你遇到的现象完全符合预期。
具体分析
1. 中间件执行与Redux同步更新
你的中间件代码执行顺序逻辑如下:
- 进入中间件,打印
MyMiddleware start - 调用
next(action):这会同步执行后续中间件和reducer1,完成对应state的更新 - Redux在state更新后,会同步触发所有
store.subscribe的回调——React-Redux正是通过这个订阅机制监听state变化,标记组件需要重渲染 - 在非React事件上下文(比如Redux订阅回调)中,React18之前会同步执行渲染逻辑,React18的自动批量更新也不会生效,因此App.jsx的
render日志会在中间件继续执行前输出 - 回到中间件逻辑,打印
MyMiddleware middle,触发reducer2的dispatch(这是另一次独立的Redux更新流程) - 打印
MyMiddleware end
2. 渲染提前触发的原因
Redux的subscribe回调是同步执行的:当next(action)完成reducer1的state更新后,Redux会立刻调用所有订阅者的回调,而React-Redux的订阅回调会直接触发组件的更新逻辑。如果当前处于同步代码块中,React会直接执行渲染(而非异步调度),因此渲染日志会插入在中间件的执行流程中。
3. 实现多reducer更新后再渲染的方案
如果想要让reducer1和reducer2都更新完成后才触发渲染,不能用中间件内二次dispatch的方式(这会触发两次独立的state更新,对应两次渲染),可以尝试以下方案:
- 让两个reducer响应同一个action:在
reducer1和reducer2中都处理SET_ACTIVE_WORKSPACE类型的action,一次dispatch完成两个state的更新 - 合并相关state到同一个slice中:如果两个state强关联,可以将它们放在同一个reducer里管理,确保更新的原子性
- 使用Redux Toolkit的
createListenerMiddleware:监听SET_ACTIVE_WORKSPACEaction,在action完成后批量更新state,但需注意React的渲染调度仍会响应每一次state变化,若要合并渲染可能需要额外处理
内容的提问来源于stack exchange,提问作者Nikita Rybak
相关产品推荐
相关产品推荐

