当前位置: 首页 > news >正文

HOW - React 组件渲染受其他无关数据影响和优化方案(含memo和props.children)

目录

  • 背景
  • 优化方案
    • 方法一:提取到父组件,分离 Timer 和 OtherSlowComponent
    • 方法二:使用 useMemo 缓存慢组件(更适用于传了 props 的场景)
    • 方法三:memo
    • 方法四:props.children
      • 为什么 props.children 能帮助优化
      • 示例:使用 props.children 优化重渲染
      • 渲染优化分析
    • 总结

背景

有如下组件:

const Timer = () => {
  const [time, setTime] = useState(0); // 每秒更新

  return (
    <>
      <h1>当前时间:{dayjs(time).format("YYYY-MM-DD HH:mm:ss")}</h1>
      <OtherSlowComponent /> // 每次 setTime 都会触发整个组件重新渲染,包括这里
    </>
  );
};

const Container = () => <Timer />;

每秒更新一次 time,导致整个 Timer 组件重新渲染,连带 ·OtherSlowComponent· 也每秒被重新渲染一次,哪怕它跟时间无关!

又或者:

import { memo } from 'react';

export const App = () => {
  const { currentUserInfo, users } = useGetInfoData();
  return (
    <div className="App">
      <CurrentUserInfo data={currentUserInfo} />
      <UserInfoList users={users} />
    </div>
  );
};

假如 currentUserInfo 更新,也会导致 UserInfoList 组件的重新渲染。

优化方案

方法一:提取到父组件,分离 Timer 和 OtherSlowComponent

const Container = () => {
  return (
    <>
      <Timer />
      <OtherSlowComponent />
    </>
  );
};

如果 OtherSlowComponentTimer 没有任何依赖关系,直接将它们并列在父组件中是最简单高效的做法,彻底避免无意义的重渲。

方法二:使用 useMemo 缓存慢组件(更适用于传了 props 的场景)

const memoizedSlowComp = useMemo(() => <OtherSlowComponent />, []);

但注意:useMemo 仅在初次渲染创建,依赖项变化时才会重新计算。

方法三:memo

export const App = () => {
  const { currentUserInfo, users } = useGetInfoData();
  return (
    <div className="App">
      <CurrentUserInfo data={currentUserInfo} />
      <UserInfoList users={users} />
    </div>
  );
};

const UserInfoList = memo(({ users }) => {
  // ...
});

方法四:props.children

为什么 props.children 能帮助优化

如果你把慢组件 OtherSlowComponent 作为 children 传进去,并且 Timer 本身不关心它、也不依赖它的任何状态变化,那就可以很好地“托管”渲染时机 —— 只要父组件不变,它不会重渲!

示例:使用 props.children 优化重渲染

const Container = () => {
  return (
    <Timer>
      <OtherSlowComponent />
    </Timer>
  );
};

const Timer = ({ children }: { children: React.ReactNode }) => {
  const [time, setTime] = useState(new Date());

  useEffect(() => {
    const intervalId = setInterval(() => setTime(new Date()), 1000);
    return () => clearInterval(intervalId);
  }, []);

  return (
    <>
      <h1>当前时间: {dayjs(time).format("YYYY-MM-DD HH:mm:ss")}</h1>
      {children}
    </>
  );
};

const OtherSlowComponent = React.memo(() => {
  console.log('💡 OtherSlowComponent 渲染了');
  return <div>这是一个渲染慢的组件</div>;
});

渲染优化分析

组件是否每秒重渲染?原因
Timer每秒更新 time
OtherSlowComponent被当作 children 静态传入,不受 time 影响,且 React.memo 避免重渲染

更多关于 props.children 的内容可以阅读 WHAT - React 组件的 props.children 属性

总结

方法是否推荐说明
使用 props.children✅✅✅非常推荐,结构清晰、性能佳
React.memo 搭配 children更加保险,确保不被不必要的重渲染触发
放到父组件里如果结构允许,这是最清晰的做法
http://www.dtcms.com/a/119376.html

相关文章:

  • equals() 和 hashCode()
  • 泛目录站群,无极多功能泛目录站群程序:AI驱动的SEO增长引擎
  • java设计模式-单例模式
  • 【unity游戏开发入门到精通——动画篇】Animator2D序列帧动画
  • 解锁健康养生密码,拥抱活力人生
  • 手写数字识别实战教程:从零实现MNIST分类器(完整代码示例)
  • 算法篇(八)【递归】
  • 【代码随想录 字符串6.实现strstr】 KMP算法。
  • 1区6.6分CHARLS最新文章解读
  • 【学习笔记】文件上传漏洞--二次渲染、.htaccess、变异免杀
  • 2025年客运从业资格证备考刷题题库
  • 7-11 分段计算居民水费
  • 告别循环!用Stream优雅处理集合
  • AI无人直播教程 ai无人直播系统 【工具下载+教程】
  • 英语学习:单复数宏
  • 【SpringCloud】从入门到精通【上】
  • 智能硬件开发革命:低代码平台+物联网
  • 山东大学离散数学第七章习题解析
  • 从零到有的游戏开发(visual studio 2022 + easyx.h)
  • HTML5元素
  • Redis主从复制原理
  • 网络安全小知识课堂(最终完结版)
  • 【10】搭建k8s集群系列(二进制部署)之安装Dashboard和CoreDNS
  • delphi idtcpserver 搭建tcp ,ssl协议服务端
  • 一文详解OpenCV环境搭建:Windows使用CLion配置OpenCV开发环境
  • 【Linux篇】缓冲区的工作原理:如何影响你程序的输入输出速度
  • 在集合中哪些可以为null,哪些不能为null;Java 集合中 null 值允许情况总结与记忆技巧
  • 蓝桥杯冲刺题单--二分
  • C++之nullptr
  • React-05React中props属性(传递数据),propTypes校验,类式与函数式组件props的使用