React Hook中返回HOC导致无限重渲染的原因及解决方案
React Hook返回HOC导致无限重渲染的原因与解决方案
一、无限重渲染的根源
你写的useHook每次执行时,都会生成一个全新的箭头函数组件(也就是那个返回的HOC)。当这个Hook被用在某个父组件里时,父组件每一次渲染都会调用useHook,得到一个完全新的函数引用。
React判断组件是否需要更新的逻辑里,函数组件的引用变了就会被当成“全新组件”处理——旧组件会被卸载,新组件重新挂载。而挂载过程又会触发useHook执行,再次生成新的组件,形成无限循环。
另外,你通过API获取title的逻辑,如果是用useState存值的话,API请求完成更新state会触发父组件重渲染,这又会让useHook返回新组件,进一步加重循环。
二、必须用useCallback吗?
没错,用useCallback包裹返回的箭头函数是解决这个问题的关键,它能让函数的引用在依赖项不变时保持稳定。
修改后的代码示例:
function useHook(){ const [title, setTitle] = useState(''); // 用useEffect确保API只在挂载时请求一次 useEffect(() => { fetch('/api/get-title') .then(res => res.text()) .then(gotTitle => setTitle(gotTitle)); }, []); // 用useCallback锁定函数引用,依赖项是title return useCallback((props) => <Component title={title} {...props}/>, [title]); }
这样一来,只有当title发生变化时,返回的HOC组件引用才会更新,避免了不必要的组件卸载和挂载,自然终止了无限重渲染的循环。
三、额外要注意的点
- API请求一定要放在
useEffect里,并且加空依赖数组,保证只在组件挂载时请求一次,避免重复请求引发的额外重渲染。 - 如果HOC需要用到其他外部值,记得把这些值也加入
useCallback的依赖数组中,确保组件能正确响应依赖变化。
内容的提问来源于stack exchange,提问作者D.B.K
相关产品推荐
相关产品推荐

