You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 21:54:18