Redux useSelector对React组件渲染的影响及重渲染疑问
Redux useSelector 对 React 组件渲染的影响及你的问题解答
核心结论
你当前的代码里,当words变化时,Word组件会触发重渲染——这和useEffect的依赖数组无关,问题出在useAppSelector的使用方式上。
原因解释
Redux的useSelector默认用**浅比较(===)**来判断是否触发组件重渲染:
- 每次Redux状态更新时,它都会执行你传入的选择器函数(也就是
state => state) - 把这次的返回值和上一次的返回值做对比
- 如果两个值不相等(引用变了就算),就会让组件重渲染
你现在直接返回整个state对象,只要state里任何属性(比如history.words)变化,整个state的引用就会更新,浅比较就会判定为“值变了”,组件就会重渲染,哪怕你根本没在组件里用到words。
另外要明确:useEffect的依赖数组只控制useEffect回调的执行时机,不影响组件本身的重渲染逻辑。
解决办法:让组件只在letters变化时重渲染
方案1:只选择需要的letters(最简方案)
如果你的组件里不需要用到words,直接让useSelector只返回letters即可:
function Word() { // 只提取需要的letters,而非整个state const letters = useAppSelector(state => state.history.letters) useEffect(() => { }, [letters]) return ( <div> </div> ) }
这种情况下,只有当letters本身的引用或值变化时,useSelector才会判定为更新,触发组件重渲染,words的变化完全不会影响。
方案2:若需同时获取words但不想因它触发重渲染(用记忆化选择器)
如果组件确实需要用到words,但只想在letters变化时重渲染,可以用reselect库创建记忆化的选择器,确保只有目标值变化时才返回新引用:
import { createSelector } from 'reselect' // 创建基础选择器 const selectHistory = state => state.history // 记忆化选择器:只有当history里的letters真的变化时,才返回新值 const selectLetters = createSelector( [selectHistory], history => history.letters ) // 同理,words的选择器也会被记忆化 const selectWords = createSelector( [selectHistory], history => history.words ) function Word() { const letters = useAppSelector(selectLetters) const words = useAppSelector(selectWords) useEffect(() => { }, [letters]) return ( <div> </div> ) }
这里selectLetters会缓存结果,只有当history.letters实际变化时才会返回新值,所以哪怕words变了,selectLetters的返回值不变,组件就不会重渲染。
内容的提问来源于stack exchange,提问作者ruslanonly
相关产品推荐
相关产品推荐

