React中使用useCallback仍导致子组件随父点击重渲染的问题
问题分析与解决
为什么子组件还是会重渲染?
你用了useCallback和memo却没达到预期,核心问题出在useCallback的依赖数组上:
当前handleClick的依赖包含num,每次点击父组件按钮更新num时,useCallback都会返回一个全新的函数实例。子组件的memo是浅比较props引用的,既然handleParentClick的引用变了,子组件自然会触发重渲染。
看这段父组件代码就能明白:
const handleClick = useCallback(() => { setNum(num + 1); }, [num]); // num一变,函数就重新创建
怎么修复?
改用函数式更新来修改num,这样就不用把num放进useCallback的依赖数组,handleClick的引用会一直稳定,子组件就不会因为这个props变化而重渲染。
修改后的父组件代码:
export default function App() { const [num, setNum] = useState(0); // 函数式更新,依赖数组为空 const handleClick = useCallback(() => { setNum(prevNum => prevNum + 1); }, []); console.log("parent renders"); return ( <div className="App"> <p>Parent's num {num}</p> <button onClick={handleClick}>Update num</button> <Child handleParentClick={handleClick} /> </div> ); }
补充说明
memo只做浅比较,只要props的引用没变,就不会触发重渲染;哪怕函数逻辑完全一样,引用变了也会重渲染。useCallback的核心是依赖不变时保持函数引用稳定,如果依赖项频繁变化,它就起不到缓存函数的作用了。
内容的提问来源于stack exchange,提问作者Murtuza
相关产品推荐
相关产品推荐

