”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 掌握 React 重新渲染:如何避免常见陷阱

掌握 React 重新渲染:如何避免常见陷阱

发布于2024-11-03
浏览:335

Mastering React Re-renders: How to Avoid Common Pitfalls

1.介绍

想象一下:您刚刚构建了一个时尚、功能丰富的 React 应用程序,但突然间,性能开始下降。按钮感觉迟钝,数据更新时间太长,而且你不知道为什么。如果这听起来很熟悉,那么您并不孤单。如果处理不当,React 重新渲染通常是性能问题背后的无声罪魁祸首。

掌握 React 中的重新渲染对于旨在构建高效、可扩展应用程序的 Web 开发人员至关重要。让我们深入研究 React 重新渲染的工作原理,并发现优化性能、避免常见陷阱并将您的 React 应用程序转变为极快体验的实用策略。

2. React 重新渲染如何工作?

React 的重新渲染机制是其最强大的功能之一。它允许您的应用程序根据状态或属性的变化动态更新 UI。但是,如果不进行优化,此过程可能会导致不必要的重新渲染,从而导致性能下降。

简单来说,React 每次都会重新渲染:

  1. 组件的状态发生变化。
  2. 组件接收新的 props。
  3. 父组件重新渲染。

但是当组件重新渲染过于频繁时会发生什么?浏览器必须重新绘制屏幕,​​从而导致动画卡顿、交互缓慢和用户沮丧。现在,问问自己:有多少次您的应用程序感觉速度很慢,而您却无法确切地指出原因?

3.为什么过度重新渲染会损害性能

过多的重新渲染会产生多米诺骨牌效应,使您的整个应用程序变得缓慢。每次重新渲染发生时:

  1. React 使更改与虚拟 DOM 协调。
  2. 它计算对实际 DOM 进行的最少更新。
  3. 浏览器重新绘制屏幕。

在小型应用程序中,这可能不明显。但在具有深度嵌套组件和复杂状态管理的大型应用程序中,即使是最小的不必要的重新渲染也可能会形成性能瓶颈。

这是一个简单的例子:

const UserList = ({ users }) => {
  return users.map(user => 
{user.name}
); }; // Inside a parent component:

现在想象一下,每次父组件更新时,这个 UserList 都会重新呈现,即使用户没有更改。这就是问题所在。我们如何防止这种不必要的重新渲染?

4.常见陷阱(以及如何避免它们)

陷阱 1:不记忆函数和对象

每次父组件重新渲染时,它都会创建新的函数和对象引用,即使实际值没有改变。这会导致子组件不必要地重新渲染。

操作:使用 useCallback 和 useMemo 挂钩来记忆函数和对象。

const ParentComponent = () => {
  const handleClick = useCallback(() => {
    // some function logic
  }, []);

  const userDetails = useMemo(() => ({ name: "Rajesh", age: 30 }), []);

  return ;
};

为什么有效: 记忆化可以防止在每次重新渲染时创建新的函数和对象引用,从而减少子组件中不必要的渲染。

陷阱 2:将内联函数或对象作为 Props 传递

每次组件渲染时都会创建内联函数或对象,导致接收组件重新渲染,即使实际值没有更改。

操作:在组件外部声明函数和对象或使用记忆挂钩。

// Avoid this:
 console.log("clicked")} />

// Instead:
const handleClick = useCallback(() => console.log("clicked"), []);

陷阱3:未能使用React.memo

一些组件本质上是纯粹的——它们总是在给定相同的 props 的情况下渲染相同的输出。然而,如果没有 React.memo,当父组件重新渲染时,它们仍然会重新渲染。

操作:用 React.memo 包裹功能组件,以防止不必要的重新渲染。

const ChildComponent = React.memo(({ data }) => {
  return 
{data.name}
; });

为什么有效: React.memo 确保组件仅在其 props 更改时重新渲染,避免冗余渲染。

5.如何跟踪和调试 React 重新渲染

有没有想过,“为什么我的组件会重新渲染?” React DevTools 提供了一种很好的方法来跟踪渲染并了解哪里出了问题。

  1. 启用“突出显示更新”:这会显示哪些组件正在重新渲染。
  2. 使用“Profiler”选项卡:它显示渲染计时并帮助识别瓶颈。

您还可以使用像这样的自定义挂钩来记录重新渲染:

const useWhyDidYouRender = (componentName, props) => {
  const previousProps = useRef(props);

  useEffect(() => {
    if (previousProps.current !== props) {
      console.log(`${componentName} re-rendered`);
      previousProps.current = props;
    }
  });
};

6。优化 React 重新渲染的最佳实践

1.在需要时提升状态,但并非总是如此

有时,将状态提升到更高的组件会导致子组件不必要的重新渲染。相反,尽可能在本地管理状态。

2.明智地使用密钥

渲染列表时,确保每个项目都有一个稳定、唯一的 key prop。这有助于 React 通过识别哪些项目已更改来优化重新渲染。

3.避免重新渲染未安装的组件

这可能会导致内存泄漏和性能问题。使用 useEffect 清理函数来避免在未挂载的组件中重新渲染。

useEffect(() => {
  return () => {
    // cleanup logic here
  };
}, []);

7.总结:掌握 React 重新渲染

简而言之,React 重新渲染可能是性能问题的隐藏根源,但通过正确的技术,您可以防止不必要的重新渲染,保持应用程序快速运行,并确保流畅的用户体验。

  • 记忆函数和对象以避免重新渲染子组件。
  • 使用 React.memo 停止纯组件中不必要的重新渲染。
  • 利用 React DevTools 跟踪、了解和调试性能瓶颈。

8.实际应用:通过有意的重新渲染提高性能

下次你优化 React 应用程序时,请批判性地思考每次重新渲染。它们有必要吗?如果你记住这个函数会发生什么?通过应用这些策略,您将编写更精简、更快的 React 代码,并避免即使是最有经验的开发人员也会遇到的常见陷阱。


最终想法: 既然您已经了解了 React 重新渲染的细节,请继续将这些优化应用到您自己的应用程序中。您不仅会看到更好的性能,还会获得编写可扩展、可维护的 React 代码的信心!


版本声明 本文转载于:https://dev.to/paharihacker/mastering-react-re-renders-how-to-avoid-common-pitfalls-k01?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • Python中何时用"try"而非"if"检测变量值?
    Python中何时用"try"而非"if"检测变量值?
    使用“ try“ vs.” if”来测试python 在python中的变量值,在某些情况下,您可能需要在处理之前检查变量是否具有值。在使用“如果”或“ try”构建体之间决定。“ if” constructs result = function() 如果结果: 对于结果: ...
    编程 发布于2025-07-14
  • CSS强类型语言解析
    CSS强类型语言解析
    您可以通过其强度或弱输入的方式对编程语言进行分类的方式之一。在这里,“键入”意味着是否在编译时已知变量。一个例子是一个场景,将整数(1)添加到包含整数(“ 1”)的字符串: result = 1 "1";包含整数的字符串可能是由带有许多运动部件的复杂逻辑套件无意间生成的。它也可以是故意从单个真理...
    编程 发布于2025-07-14
  • 反射动态实现Go接口用于RPC方法探索
    反射动态实现Go接口用于RPC方法探索
    在GO 使用反射来实现定义RPC式方法的界面。例如,考虑一个接口,例如:键入myService接口{ 登录(用户名,密码字符串)(sessionId int,错误错误) helloworld(sessionid int)(hi String,错误错误) } 替代方案而不是依靠反射...
    编程 发布于2025-07-14
  • 如何使用Python的请求和假用户代理绕过网站块?
    如何使用Python的请求和假用户代理绕过网站块?
    如何使用Python的请求模拟浏览器行为,以及伪造的用户代理提供了一个用户 - 代理标头一个有效方法是提供有效的用户式header,以提供有效的用户 - 设置,该标题可以通过browser和Acterner Systems the equestersystermery和操作系统。通过模仿像Chro...
    编程 发布于2025-07-14
  • MySQL中如何高效地根据两个条件INSERT或UPDATE行?
    MySQL中如何高效地根据两个条件INSERT或UPDATE行?
    在两个条件下插入或更新或更新 solution:的答案在于mysql的插入中...在重复键更新语法上。如果不存在匹配行或更新现有行,则此功能强大的功能可以通过插入新行来进行有效的数据操作。如果违反了唯一的密钥约束。实现所需的行为,该表必须具有唯一的键定义(在这种情况下为'名称'...
    编程 发布于2025-07-14
  • 找到最大计数时,如何解决mySQL中的“组函数\”错误的“无效使用”?
    找到最大计数时,如何解决mySQL中的“组函数\”错误的“无效使用”?
    如何在mySQL中使用mySql 检索最大计数,您可能会遇到一个问题,您可能会在尝试使用以下命令:理解错误正确找到由名称列分组的值的最大计数,请使用以下修改后的查询: 计数(*)为c 来自EMP1 按名称组 c desc订购 限制1 查询说明 select语句提取名称列和每个名称...
    编程 发布于2025-07-14
  • 为什么使用Firefox后退按钮时JavaScript执行停止?
    为什么使用Firefox后退按钮时JavaScript执行停止?
    导航历史记录问题:JavaScript使用Firefox Back Back 此行为是由浏览器缓存JavaScript资源引起的。要解决此问题并确保在后续页面访问中执行脚本,Firefox用户应设置一个空功能。 警报'); }; alert('inline Alert')...
    编程 发布于2025-07-14
  • 为什么我会收到MySQL错误#1089:错误的前缀密钥?
    为什么我会收到MySQL错误#1089:错误的前缀密钥?
    mySQL错误#1089:错误的前缀键错误descript [#1089-不正确的前缀键在尝试在表中创建一个prefix键时会出现。前缀键旨在索引字符串列的特定前缀长度长度,可以更快地搜索这些前缀。了解prefix keys `这将在整个Movie_ID列上创建标准主键。主密钥对于唯一识别...
    编程 发布于2025-07-14
  • 如何高效地在一个事务中插入数据到多个MySQL表?
    如何高效地在一个事务中插入数据到多个MySQL表?
    mySQL插入到多个表中,该数据可能会产生意外的结果。虽然似乎有多个查询可以解决问题,但将从用户表的自动信息ID与配置文件表的手动用户ID相关联提出了挑战。使用Transactions和last_insert_id() 插入用户(用户名,密码)值('test','test...
    编程 发布于2025-07-14
  • 哪种方法更有效地用于点 - 填点检测:射线跟踪或matplotlib \的路径contains_points?
    哪种方法更有效地用于点 - 填点检测:射线跟踪或matplotlib \的路径contains_points?
    在Python Matplotlib's path.contains_points FunctionMatplotlib's path.contains_points function employs a path object to represent the polygon.它...
    编程 发布于2025-07-14
  • eval()vs. ast.literal_eval():对于用户输入,哪个Python函数更安全?
    eval()vs. ast.literal_eval():对于用户输入,哪个Python函数更安全?
    称量()和ast.literal_eval()中的Python Security 在使用用户输入时,必须优先确保安全性。强大的python功能eval()通常是作为潜在解决方案而出现的,但担心其潜在风险。本文深入研究了eval()和ast.literal_eval()之间的差异,突出显示其安全性含义...
    编程 发布于2025-07-14
  • 如何从PHP中的Unicode字符串中有效地产生对URL友好的sl。
    如何从PHP中的Unicode字符串中有效地产生对URL友好的sl。
    为有效的slug生成首先,该函数用指定的分隔符替换所有非字母或数字字符。此步骤可确保slug遵守URL惯例。随后,它采用ICONV函数将文本简化为us-ascii兼容格式,从而允许更广泛的字符集合兼容性。接下来,该函数使用正则表达式删除了不需要的字符,例如特殊字符和空格。此步骤可确保slug仅包含...
    编程 发布于2025-07-14
  • 如何处理PHP文件系统功能中的UTF-8文件名?
    如何处理PHP文件系统功能中的UTF-8文件名?
    在PHP的Filesystem functions中处理UTF-8 FileNames 在使用PHP的MKDIR函数中含有UTF-8字符的文件很多flusf-8字符时,您可能会在Windows Explorer中遇到comploreer grounder grounder grounder gro...
    编程 发布于2025-07-14
  • 如何有效地转换PHP中的时区?
    如何有效地转换PHP中的时区?
    在PHP 利用dateTime对象和functions DateTime对象及其相应的功能别名为时区转换提供方便的方法。例如: //定义用户的时区 date_default_timezone_set('欧洲/伦敦'); //创建DateTime对象 $ dateTime = ne...
    编程 发布于2025-07-14

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3