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

父组件状态更新时如何避免子组件不必要的重复渲染?

问题根因

你当前的代码出现多余重渲染是两个原因共同导致的:

  • 父组件Home状态更新时,默认会重渲染所有嵌套在其JSX结构内的子组件,不管子组件是否依赖这个状态
  • 传递给Context Provider的value是每次渲染都新创建的对象,哪怕内部存储的字段值没有变化,引用地址的变更也会触发所有消费该Context的组件重渲染
修改方案

方法1:直接传递原始值到Context+用memo包裹子组件

1. 修改Home.js代码

import React, { useState, createContext } from "react";
import { User1, User2, User3 } from "./User";

export const UserContext = createContext(null);
export const TypeContext = createContext(null); 

const Home = () => {
  const [user, setUser] = useState("User");
  const [type, setType] = useState("Free");
  return (
    <>
      <input type="text" onChange={(event) => setUser(event.target.value)} />
      <br />
      <input type="text" onChange={(event) => setType(event.target.value)} />
      {/* 去掉多余的对象包裹,直接传值 */}
      <UserContext.Provider value={user}>
        <User1 />
      </UserContext.Provider>
      <TypeContext.Provider value={type}>
        <User2 />
      </TypeContext.Provider>
    </>
  );
};

export default Home;

2. 修改User.js代码

import React, { useContext } from "react";
import { UserContext, TypeContext } from "./Home";

// 用React.memo包裹组件,阻止父组件重渲染带来的默认更新
export const User1 = React.memo(() => {
  // 直接取Context值,不需要解构
  const user = useContext(UserContext);
  console.log("user1");
  return <h1>Username is {user}</h1>;
 });

export const User2 = React.memo(() => {
  const type = useContext(TypeContext);
  console.log("user2");
  return <h1>用户类型是 {type}</h1>;
});

export const User3 = React.memo((props) => {
  console.log("user3");
  return <h2>My Props {props.title}</h2>;
});

方法2:如果需要在Context中传递多个值,用useMemo包裹Context的value

如果你的Context需要同时传递多个字段和方法,不能直接传原始值,就用useMemo保证只有依赖变化时才更新value的引用:

// Home.js 中新增useMemo处理
import React, { useState, createContext, useMemo } from "react";
// ...其他代码不变
const Home = () => {
  const [user, setUser] = useState("User");
  const [type, setType] = useState("Free");
  // 只有user变化时才会生成新的userContextValue
  const userContextValue = useMemo(() => ({
    user,
    setUser
  }), [user])
  // 只有type变化时才会生成新的typeContextValue
  const typeContextValue = useMemo(() => ({
    type,
    setType
  }), [type])
  return (
    <>
      <input type="text" onChange={(event) => setUser(event.target.value)} />
      <br />
      <input type="text" onChange={(event) => setType(event.target.value)} />
      <UserContext.Provider value={userContextValue}>
        <User1 />
      </UserContext.Provider>
      <TypeContext.Provider value={typeContextValue}>
        <User2 />
      </TypeContext.Provider>
    </>
  );
};

对应User.js的消费逻辑不用改,还是按原来的结构解构取值即可。

生效原理
  • React.memo会对组件接收的props做浅比较,User1和User2没有外部传入的props,父组件重渲染时props对比结果为无变化,就不会触发默认重渲染,只有组件依赖的Context变化时才会更新
  • 直接传原始值/用useMemo包裹Context value,保证只有Context存储的实际内容变化时,才会更新Context的引用,不会出现无意义的Context变更触发重渲染

内容的提问来源于stack exchange,提问作者Ankita Jaiswal

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 04:54:05