Redux Toolkit使用createSelector后组件仍异常重渲染问题排查
问题根因
- 第一层原因:父组件
App触发了重渲染,且TitleList未做渲染拦截
你的App组件通过useSelector订阅了state.titles.title字段,每次输入框内容变更触发titleChangeaction时,title字段更新会导致App组件重渲染。React默认的渲染规则是:父组件重渲染时,所有子组件无论props是否变化,都会默认跟随重渲染,这是你看到TitleList频繁重渲染的核心原因。 - 第二层验证:你的selector记忆化逻辑是正常的
你写的createSelector依赖的是state.titles.titles数组,输入框变更只会修改state.titles.title,不会修改titles数组的引用,因此createSelector不会重新执行filter逻辑,返回的数组引用和上一次完全一致,useSelector本身不会触发TitleList的重渲染。
解决方案
给TitleList组件包裹React.memo即可,它会对组件的入参做浅比较,只要props没有变化,就会阻止父组件重渲染带来的子组件无效重渲染:
const Titlelist = React.memo(() => { const allTitles = useSelector(selectTitlesLengthWithReselect); console.log("RENDERED"); return ( <div> {allTitles.map((elem) => ( <li key={elem.id}>{elem.title}</li> ))} </div> ) })
补充验证方法
你可以临时注释掉App组件中useSelector取title的逻辑,改为用非受控输入框测试,此时App不会因为title变更重渲染,就能看到TitleList不会跟着输入操作触发重渲染,进一步验证你的selector写法是正确的。
内容的提问来源于stack exchange,提问作者Ek4m
相关产品推荐
相关产品推荐

