useReducer空dispatch延迟触发额外渲染:现象名称及规避方法问询
问题解答
现象名称
目前这个延迟触发后集中渲染的现象没有统一的专属术语,一般会描述成**"无效dispatch积累导致的批量渲染触发"**——简单说就是你多次调用了不会改变状态的dispatch,这些dispatch会被React暂时存起来,等后续有真正改变状态的dispatch执行时,之前存的所有无效dispatch会被一起处理,导致组件额外多渲染好几次。
避免方法
核心思路就是别调用那些不会改变状态的dispatch,具体可以这么做:
- 触发前先判断,跳过无效dispatch:比如你这个例子里的"pass"按钮,既然知道点击它不会改变状态,那就直接不调用
dispatch,改成这样:<button onClick={() => { /* 无状态变化,无需调用dispatch */ }}>Pass</button> - 在reducer里提前过滤(仅作补充):如果业务上必须要通过dispatch传递这个action,在reducer里可以判断后直接返回原状态,但这种方式只能跳过单次的无效渲染,没法解决之前积累的无效dispatch导致的后续额外渲染,所以更推荐第一种方式:
function reducer(state, action) { switch (action.type) { case "increment": return { count: state.count + 1 }; case "pass": // 直接返回原状态,React会跳过本次渲染,但无法解决积累问题 return state; default: throw new Error(); } }
另外提一句,React 18及以后的版本,因为并发渲染的优化逻辑,这类问题的表现会减轻不少,但最根本的解决办法还是避免不必要的dispatch调用。
内容的提问来源于stack exchange,提问作者Matt
相关产品推荐
相关产品推荐

