”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 避免 React 中不必要的重新渲染

避免 React 中不必要的重新渲染

发布于2024-11-08
浏览:929

Avoiding Unnecessary Re-renders in React

构建高性能 React 应用程序的关键之一是避免不必要的重新渲染。 React 的渲染引擎非常高效,但防止在不需要的地方重新渲染仍然至关重要。在这篇文章中,我们将介绍常见错误以及如何避免这些错误。


1. 使用 React.memo 记忆组件

当组件的 props 没有改变时,Memoization 可以帮助你跳过重新渲染。然而,如果不实现自定义比较函数,很容易误用 React.memo。

错误用法:

const MemoizedComponent = React.memo(MyComponent);

这仅检查 props 引用是否已更改,这可能并不总是足够的。

正确用法:

const MemoizedComponent = React.memo(MyComponent, (prevProps, nextProps) => {
  return prevProps.itemId === nextProps.itemId;
});

这里,我们使用自定义比较函数,仅当 itemId 属性发生变化时才会触发重新渲染。


2. 避免过多使用内联函数

在 JSX 中使用内联函数可能会导致不必要的重新渲染,因为 React 在每次渲染时都会将新函数视为新的 prop。

错误用法:

function ButtonComponent() {
  return ;
}

这会导致在每次渲染时重新创建handleClick,从而导致不必要的重新渲染。

正确用法:

import { useCallback } from 'react';

function ButtonComponent() {
  const handleClick = useCallback(() => {
    // Handle click logic
  }, []);

  return ;
}

通过使用 useCallback,我们记住了 handleClick 函数,从而防止在每次渲染时进行不必要的重新创建。


3. 利用 PureComponent

使用类组件时,使用 React.PureComponent 可确保组件仅在其 props 或状态更改时重新渲染。如果您使用 React.Component,可能会导致不必要的重新渲染。

错误用法:

class CardComponent extends React.Component {
  // Component logic
}

正确用法:

class CardComponent extends React.PureComponent {
  // Component logic
}

通过扩展 React.PureComponent,React 将浅层比较 props 和 state,避免不必要的重新渲染。


4. 优化功能组件中的useSelector

当使用react-redux中的useSelector时,仅选择状态的必要部分非常重要。

错误用法:

import { useSelector } from 'react-redux';

const DataComponent = () => {
  const globalState = useSelector((state) => state);
  // Render logic
};

每当状态的任何部分发生变化时,这将导致组件重新渲染。

正确用法:

import { useSelector } from 'react-redux';

const DataComponent = () => {
  const selectedData = useSelector((state) => state.specificSlice);
  // Render logic based on specific slice
};

通过仅选择状态的必要部分,可以最大限度地减少重新渲染。


5. 在类组件中实现shouldComponentUpdate

对于不扩展 PureComponent 的类组件,手动实现 shouldComponentUpdate 可以更精细地控制组件何时重新渲染。

错误用法:

class ListItem extends React.Component {
  // Component logic
}

每次父组件渲染时都会重新渲染,即使 props 和 state 没有改变。

正确用法:

class ListItem extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    return this.props.itemId !== nextProps.itemId || this.state.value !== nextState.value;
  }

  // Component logic
}

通过自定义shouldComponentUpdate,我们确保组件仅在itemId属性或值状态发生变化时重新渲染。


结论

通过采用这些技术,您可以显着减少 React 应用程序中不必要的重新渲染,从而获得更好的性能。使用 React.memo 实现记忆化、利用 PureComponent 以及微调 shouldComponentUpdate 是优化 React 组件的关键策略。

了解何时以及如何优化渲染可以通过提供更快、响应更灵敏的应用程序来极大地增强用户体验。


参考:

  1. 极客们的极客们。 (2023)。 React 中的记忆化是什么?
  2. 同步融合。 (2024)。 React 中的记忆化
  3. Hygraph。 (2024)。什么是 React Memo 以及如何使用它?
  4. Refine.dev。 (2024)。带有示例的 React 备忘录指南

如果您发现本指南有用,请考虑与其他人分享! ?


本博客提供了更新且全面的概述,介绍如何避免 React 应用程序中不必要的重新渲染,同时结合最佳实践并更改变量名称,以确保现代 Web 开发实践中的清晰度和相关性。

引用:
[1] https://www.geeksforgeeks.org/what-is-memoization-in-react/
[2] https://stackoverflow.com/questions/74013864/why-arent-all-react-components-wrapped-with-react-memo-by-default
[3] https://www.syncfusion.com/blogs/post/what-is-memoization-in-react
[4] https://hygraph.com/blog/react-memo
[5] https://refine.dev/blog/react-memo-guide/
[6] https://dmitripavlutin.com/use-react-memo-wisely/
[7] https://www.topcoder.com/thrive/articles/memoization-in-react-js
[8] https://react.dev/reference/react/memo

版本声明 本文转载于:https://dev.to/vyan/avoiding-unnecessary-re-renders-in-react-172k?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 冰冷的池塘如何帮助您理解 C++ 中未定义的行为?
    冰冷的池塘如何帮助您理解 C++ 中未定义的行为?
    理解初学者的未定义行为对于新程序员来说,未定义行为是一个很难掌握的概念,特别是当他们在工作中遇到过它时实践其具体实施。为了帮助新手理解避免未定义行为的重要性,可以采用一个有效的类比。想象一个结冰的池塘,其中冰的厚度和稳定性是不可预测的。假设你走过池塘一次,它成立。这能保证每次都能安全通过吗?当然不是...
    编程 发布于2024-11-08
  • 在 Go 中使用 WebSocket 进行实时通信
    在 Go 中使用 WebSocket 进行实时通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    编程 发布于2024-11-08
  • 如何在Vue.js组件中动态加载外部JS脚本?
    如何在Vue.js组件中动态加载外部JS脚本?
    在 Vue.js 组件中动态加载外部 JS 脚本使用支付网关时,集成促进交易的外部脚本变得必要。然而,通常不希望在初始页面加载时加载这些脚本。这就是 Vue.js 提供的解决方案,用于在特定组件中动态加载外部脚本。要实现此目的,请利用 Vue.js 组件中的 Mounted() 生命周期挂钩。 Mo...
    编程 发布于2024-11-08
  • 如何使用 Foreach 循环查找 PHP 数组中的最后一个元素?
    如何使用 Foreach 循环查找 PHP 数组中的最后一个元素?
    使用 PHP 的 foreach 循环查找数组中的最后一个元素在 PHP 中,在 foreach 循环中访问数组的最后一个元素需要与 Java 相比,这是一种更细致的方法,可以直接检查数组长度。使用计数和增量要确定最后一个元素,您可以利用 count( ) 函数,返回数组中的元素数量:$numIte...
    编程 发布于2024-11-08
  • 如何解决Python中的循环依赖问题?
    如何解决Python中的循环依赖问题?
    Python 中的循环依赖解析在 Python 中,当模块相互依赖其定义时,可能会遇到循环依赖。当两个文件(node.py 和 path.py)分别定义类 Node 和 Path,并且每个文件都引用另一个文件时,就会出现这样的情况。最初,path.py 导入 node.py 来访问 Node目的。然...
    编程 发布于2024-11-08
  • rnr:适用于每个项目运行脚本的工具
    rnr:适用于每个项目运行脚本的工具
    嘿,JavaScript 和 TypeScript 开发者! ?您是否厌倦了使用不同的命令来启动各种 JS 项目?好吧,我有一些令人兴奋的消息要告诉你!我创建了一个名为 rnr(发音为“runner”)的工具,它使运行任何 JavaScript 或 TypeScript 项目变得超级容易。 ...
    编程 发布于2024-11-08
  • Java 的可选类型如何简化“Get”调用链中空值的处理?
    Java 的可选类型如何简化“Get”调用链中空值的处理?
    使用可选的“Get”调用链安全导航在 Java 编程中,经常会遇到“get”调用链,如下所示:house.getFloor(0).getWall(WEST).getDoor().getDoorknob();为了避免潜在的 NullPointerExceptions,开发人员通常采用详细的 null ...
    编程 发布于2024-11-08
  • 大泥球:理解反模式以及如何避免它
    大泥球:理解反模式以及如何避免它
    前端开发中最臭名昭著的架构反模式可能是大泥球。术语“大泥球”适用于没有明显结构或模块化组织的系统。代码库有机且混乱地增长,成为维护的噩梦。这是许多开发人员发现自己所处的情况,特别是当他们面临着按时完成任务并开发大量功能的压力时。 这就是当前文章的内容:大泥球反模式以及前端开发中的示例,为什么它如此常...
    编程 发布于2024-11-08
  • 如何正确使用带 Map 参数的“reflect.Call”函数?
    如何正确使用带 Map 参数的“reflect.Call”函数?
    解决reflect包中的.Call使用问题在reflect包中使用.Call函数时,遵守所需的参数格式至关重要。本文将指导您完成正确使用 .Call 函数并操作 in 变量以满足目标方法的过程。提供的示例代码中:params := "some map[string][]string&quo...
    编程 发布于2024-11-08
  • 如何使用 HTML 和 CSS 创建翻页卡动画
    如何使用 HTML 和 CSS 创建翻页卡动画
    在这篇文章中,我们将了解如何使用 HTML 和 CSS 以及渐变背景创建时尚的 3D 翻转卡片动画。 访问我的网站 了解结构 我们将使用卡片的两侧(正面和背面)来创建翻转效果。此效果将在悬停时使用 CSS 过渡激活。 <div class="card"> <...
    编程 发布于2024-11-08
  • Python 中的 len() 函数有多高效?
    Python 中的 len() 函数有多高效?
    Python 中 len() 函数的成本影响len() 函数是 Python 内置功能的组成部分,提供有关各种数据结构的长度的信息。具体来说,它通常与列表、元组、字符串和字典一起使用,以确定它们所包含的元素或字符的数量。与直观的感知相反,len() 函数的计算成本保持不变跨越所有上述数据类型。这意味...
    编程 发布于2024-11-08
  • 如何在 Java 中将 Long 值转换为字节数组并返回?
    如何在 Java 中将 Long 值转换为字节数组并返回?
    在 Java 中将 Long 转换为字节数组并返回在 Java 中,将 long 基本数据类型转换为字节数组 (byte[] ),反之亦然是各种操作的常见任务,例如通过 TCP 连接发送数据。下面是实现此转换的全面解决方案:Long 到 Byte Arraypublic byte[] longToB...
    编程 发布于2024-11-08
  • 如何使用 Selenium 在 Google Chrome 中模拟 Microsoft Edge Mobile?
    如何使用 Selenium 在 Google Chrome 中模拟 Microsoft Edge Mobile?
    使用 Selenium 更改 Google Chrome 中的用户代理在 Selenium 自动化脚本中,为浏览器窗口设置特定的用户代理对于模拟设备行为和确保网站渲染至关重要正如预期的那样。在这种情况下,我们的目标是将 Google Chrome 中的用户代理修改为 Microsoft Edge M...
    编程 发布于2024-11-08
  • 哪种 MySQL 获取函数适合您的 PHP 应用程序:`mysql_fetch_array`、`mysql_fetch_assoc` 和 `mysql_fetch_object` 的比较
    哪种 MySQL 获取函数适合您的 PHP 应用程序:`mysql_fetch_array`、`mysql_fetch_assoc` 和 `mysql_fetch_object` 的比较
    比较 mysql_fetch_array、mysql_fetch_assoc 和 mysql_fetch_object:综合分析mysql 函数系列在从 MySQL 查询中检索结果中起着至关重要的作用在 PHP 中。在这些函数中,mysql_fetch_array、mysql_fetch_assoc...
    编程 发布于2024-11-08
  • Lerna – Monorepo 管理的关键
    Lerna – Monorepo 管理的关键
    欢迎回到莫诺雷波城堡! 现在城堡已经建成,每个房间(项目)都已就位。但如果没有正确的管理,事情可能会变得混乱。谁来帮助城堡顺利运转?这时勒纳登场了——一位强大的巫师,拥有神奇的命令,可以让一切保持秩序。 Lerna 是您在 monorepo 土地上的向导,确保所有房间(项目)同步,所有包都链接,并且...
    编程 发布于2024-11-08

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

Copyright© 2022 湘ICP备2022001581号-3