react中为什么父组件渲染,子组件都需要重新渲染?

文章类型:React

发布者:hp

发布时间:2026-04-27

一:引言

在React 遵循“自上而下”的数据流。当父组件的状态(State)或属性(Props)发生变化触发重新渲染时,React 会递归地重新执行父组件及其所有子组件的渲染函数。

二:原因

1:React 的单向数据流与默认行为

即使子组件接收的 Props 没有发生任何变化,只要父组件重新渲染,React 默认也会重新渲染子组件。这种设计确保了视图与状态的一致性。因为父组件的渲染逻辑可能隐含地影响了子组件,重新渲染是保证 UI 正确性的最安全方式

2:引用类型的不稳定性

开发者认为子组件的 Props “看起来”没变,但子组件依然重渲染,这通常是因为 ‌引用类型(对象、数组、函数)‌ 在每次渲染时被重新创建

3:JSX 元素的新建与协调

当父组件重新执行渲染函数时,它会生成新的 Virtual DOM 树,如果子组件是在父组件的 JSX 中直接声明的(例如 <Parent><Child /></Parent>),每次父组件渲染时,<Child /> 都会被解析为一个新的 React 元素对象。

React 的协调算法会发现这个新的元素引用,为了确定是否需要更新真实 DOM,它必须调用子组件的函数以获取最新的输出进行比较。

三:解决办法

1:‌使用 React.memo‌:包裹子组件,使其仅在 Props 发生浅比较变化时才重渲染

const Child = React.memo(({ name }) => <div>{name}</div>);

2:‌稳定引用类型(useMemo 和 useCallback)

使用 useMemo 缓存对象或数组,确保在依赖项不变时返回相同的引用。

使用 useCallback 缓存函数,避免每次渲染创建新函数导致子组件(特别是被 memo 包裹的子组件)失效。

import React, { useState, memo, useMemo } from 'react';

const Child = memo(({ data }) => {
  console.log('Child 组件重新渲染了');
  return <div>{data.value}</div>;
});

const Parent = () => {
  const [count, setCount] = useState(0);

  //  正确示范:只有依赖项变化时才创建新对象
  const data = useMemo(() => ({ id: 1, value: 'example' }), []);

  return (
    <div>
      <button onClick={() => setCount(count + 1)}>更新父组件状态</button>
      <Child data={data} />
    </div>
  );
};

3:‌提升状态或拆分组件

将频繁变化的状态下移到不需要该状态的子组件之外。

将不依赖父组件状态的部分提取为独立的组件,减少受父组件渲染影响的范围

4:使用 children 模式优化

如果子组件作为 children 传递,且父组件内部状态变化不影响 children 的结构,有时可以通过合理的组件组合避免深层子树的重复渲染

上一篇node的stream
评论
0条评论遵守法律,文明用语,共同建设文明评论区

暂无评论,快来发表第一条评论吧~