React-Redux组件在store未关联state变更时重渲染如何阻止?
问题根因
你遇到的不必要重渲染核心是useSelector的取值逻辑错误导致的:
你在useSelector中直接返回了完整的state.ui对象,再从中解构header_字段。当你修改state.ui.headerWidth时,reducer返回了新的state.ui对象引用,哪怕你的组件没有用到headerWidth,shallowEqual在对比前后两次返回的state.ui对象时,会检测到headerWidth属性发生了变化,因此判定需要触发组件重渲染。
解决方法
1. 调整useSelector取值范围(成本最低的修复方案)
不要直接返回整个state.ui对象,只返回当前组件需要用到的header_字段,这样只有header_本身发生变化时才会触发组件重渲染:
// 原有错误写法 const { header_ } = useSelector((state) => state.ui, shallowEqual) // 修改后的正确写法 const header_ = useSelector((state) => state.ui.header_, shallowEqual)
修改后headerWidth的变更不会再影响当前组件的渲染。
2. 回调函数缓存优化
当前组件内的onResize、handleSort、getRef等函数每次渲染都会生成新的引用,如果子组件ResizableBox、Header等使用了React.memo优化,新的函数引用会导致子组件不必要的重渲染,可以用useCallback缓存这些函数:
const dispatch = useDispatch() const headerRef = useRef([]) const header_ = useSelector((state) => state.ui.header_, shallowEqual) // 缓存onResize const onResize = useCallback((e, {event, node, size}) => { dispatch(changeHeaderWidth(node.id, size.width)) }, [dispatch]) // 缓存handleSort const handleSort = useCallback((id) => () => { // 原有排序逻辑 }, []) // 缓存ref获取函数 const getRef = useCallback((element) => { headerRef.current.push(element) }, [])
其他注意项
你reducer代码里的actions.payload.neWidth属于拼写错误,应该是newWidth,否则修改列宽的功能不会正常生效。
内容的提问来源于stack exchange,提问作者Sai Krishna
相关产品推荐
相关产品推荐

