如何解决传递对象类型props导致React.memo未正常生效的问题
修复方案
你定位的原因完全正确:React.memo默认只做props的浅比较,每次父组件渲染时在map循环里新建input对象,就算内部value完全没变,对象引用变化也会导致浅比较不通过,触发子组件重渲染。可以按以下三种方案修复:
方案1:拆分props,取消对象传递
直接把input.value拆成单独的基础类型prop传给子组件,不要用对象包裹:
// 父组件渲染逻辑修改 return ( <Input name={el.name} placeholder={el.placeholder} inputValue={inputValue[el.name]} // 直接传字符串/数值这类基础类型 rules={rules} err={err} func={testFunc} key={el.name} /> );
基础类型只要内容不变,浅比较就会直接判定相等,React.memo就能正常拦截不必要的更新。
方案2:自定义React.memo比较规则
如果不想调整props结构,可以给React.memo加第二个参数,手写比较逻辑,只需要判断对象内部的实际值是否变化即可:
// 子组件导出逻辑修改 export default React.memo(Test, (prevProps, nextProps) => { // 所有props实际内容相等就返回true,阻止重渲染 return ( prevProps.input.value === nextProps.input.value && prevProps.name === nextProps.name && prevProps.placeholder === nextProps.placeholder && prevProps.err === nextProps.err && prevProps.func === nextProps.func ); });
注意如果testFunc是在父组件内部定义的函数,需要用useCallback包裹,否则每次父组件渲染函数引用都会变化,还是会触发重渲染。
方案3:用useMemo缓存input对象
如果一定要保留input对象的props结构,可以在父组件用useMemo缓存这个对象,只有依赖值变化时才重新生成:
// 父组件map循环内修改 const input = useMemo(() => ({ value: inputValue[el.name], }), [inputValue[el.name]]);
只要依赖项inputValue[el.name]没有变化,就会复用旧的对象引用,浅比较就能正常通过。
内容的提问来源于stack exchange,提问作者Rakesh
相关产品推荐
相关产品推荐

