React函数组件调用父方法更新状态时阻止子组件重渲染
问题根因
useCallback 生效的核心是依赖不变时返回缓存的函数引用,你的代码存在两个问题导致优化失效:
- 调用
useCallback时没有传入第二个参数(依赖数组),等价于没有做缓存,每次父组件重渲染都会生成全新的函数引用 - 就算补上依赖数组
[show],每次show状态更新后依赖值变化,依然会生成新的函数引用,传给memo包裹的子组件时,浅比较会判定props变更,触发子组件重渲染,达不到优化效果。
修复方案
使用useState的函数式更新写法,让状态更新逻辑不依赖外部的show变量,这样useCallback的依赖数组可以设为空数组,整个组件生命周期内函数引用保持稳定,配合memo即可阻止子组件不必要重渲染,同时支持多次点击调用。
修正后代码
app.js
import React, { useState, useCallback } from "react"; import Child from "./child"; export default function App() { const [show, setShow] = useState(false); console.log("App Re-render:", show); // 函数式更新取前一次状态值,不需要依赖外部show,依赖数组为空即可永久缓存函数引用 const setMyState = useCallback(() => { setShow(prevShow => !prevShow); }, []); return ( <div className="App"> <h1>Parent Component</h1> <h2>----------------------------------</h2> <Child func={setMyState}></Child> </div> ); }
child.js
原代码无需修改,memo浅比较逻辑可以正常生效:
import React, { memo } from "react"; function Child({ func }) { console.log("Child re-render"); return ( <div> <p>Child Component</p> <button onClick={func}>Call Parent Method </button> </div> ); } export default memo(Child);
效果验证
- 页面首次加载时父子组件各执行1次渲染
- 后续每次点击按钮,仅父组件打印重渲染日志,子组件不会触发无意义重渲染
- 多次点击功能正常,
show状态可以正确在true/false之间切换
内容的提问来源于stack exchange,提问作者Lalit
相关产品推荐
相关产品推荐

