”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 了解 React 应用程序中的渲染和重新渲染:它们如何工作以及如何优化它们

了解 React 应用程序中的渲染和重新渲染:它们如何工作以及如何优化它们

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

Razumevanje Renderovanja i Rerenderovanja u React Aplikacijama: Kako funkcionišu i kako ih optimizovati

当我们在 React 中创建应用程序时,我们经常会遇到术语渲染和重新渲染组件。虽然乍一看这似乎很简单,但当涉及不同的状态管理系统(如 useState、Redux)或当我们插入生命周期钩子(如 useEffect)时,事情会变得有趣。如果您希望您的应用程序快速高效,那么了解这些流程是关键。

什么是渲染?

渲染是 React 根据状态或属性在屏幕上渲染用户界面 (UI) 的过程。当你的组件第一次渲染时,它被称为第一次渲染。

初始渲染如何工作?

当组件首次“安装”到 DOM 时,会发生以下情况:

1。状态初始化:
无论你使用 useState、props 还是 Redux,都会创建组件的初始状态。

2.渲染函数:
React 循环遍历 JSX 代码并根据当前状态生成虚拟 DOM。

3.为组件的当前状态创建一个虚拟 DOM(Virtual DOM)。

4。比较(差异):
虚拟 DOM 与真实 DOM 进行比较(由于是第一次渲染,所以所有元素都会被完全渲染)。

5。显示:
该组件显示在屏幕上。
一旦组件被渲染,下一个挑战就是重新渲染。

重新渲染:何时以及为何?

每次状态或道具发生变化时都会发生重新渲染。您是否单击了更改屏幕上数字的按钮?更改了 Redux 存储中的值?所有这些操作都可能导致 React 再次渲染组件,这就是重新渲染的用武之地。

重新渲染如何工作?

状态变化检测:

  • 使用useState,当你调用setState时,React知道它需要更新组件。

  • 使用 Redux,当存储中的值发生更改时,与该状态部分关联的每个组件都会重新渲染。

渲染触发器:

当状态发生变化时,React 根据该变化创建一个新的虚拟 DOM。

比较(比较):

  • React 将新的虚拟 DOM 与旧的虚拟 DOM 进行比较,并计算要应用哪些更改。这是 React 优化渲染的一种方式。

查看更改:

  • 计算出更改后,React 将它们应用到实际的 DOM 上。因此,仅再次显示页面已更改的部分。

哪些组件被重新渲染?

并非所有组件都会受到每次更改的影响。 React 仅重新渲染那些满足以下条件的组件:

使用本地状态:
如果使用 useState,则每次调用 setState 时都会重新渲染组件。

使用 Redux 状态:
如果你的组件依赖于 Redux 状态(通过 useSelector 或 connect),当该部分状态发生变化时,它将重新渲染。

使用道具:
如果 props 值发生变化,组件将使用新值重新渲染。

渲染优化

当然,不必要地重新渲染所有组件并不总是理想的。如果我们希望应用程序快速高效地工作,这里有一些优化技巧:

1。记忆组件
React 通过 React.memo 提供组件记忆功能。如果你的组件不依赖于 props 或状态变化,你可以“记住”它,因此只有当相关值发生变化时它才会重新渲染。

例子:

const MemoizedComponent = React.memo(MyComponent);

2.函数和值的记忆

为了避免在每次渲染时重新创建函数或值,请使用 useCallback 来记忆函数并使用 useMemo 来记忆值。

  • useCallback 允许您记住函数并防止重新创建它,直到依赖项发生变化。

  • useMemo 会记住函数的结果,因此不会在每次渲染时重新计算。

例子:

const increment = useCallback(() => {
  setCount(prevCount => prevCount   1);
}, []);

const expensiveCalculation = useMemo(() => {
  return count * 2;
}, [count]);

3. Redux 优化

如果您使用 Redux,您可以使用记忆选择器(例如重新选择)进一步优化应用程序。这使得可以避免重新渲染不受状态更改影响的组件。

生命周期挂钩和渲染

在经典的React类中,我们使用shouldComponentUpdate来控制组件何时重新渲染。在功能组件中,可以使用 useEffect 和 memoization 来模拟这个概念。

结论

渲染和重新渲染对于 React 应用程序中的 UI 显示至关重要,但正确理解和优化这些过程可以区分慢速和超快的应用程序。正确使用 memoization、useCallback、useMemo 以及仔细处理 Redux,有助于避免不必要的重新渲染并保持我们的应用程序快速响应。

示例代码:渲染和重新渲染实际操作
下面是一个使用 useState、Redux 和 memoization 来优化渲染的组件示例:

import React, { useState, useEffect, useCallback, useMemo } from 'react';
import { useSelector, useDispatch } from 'react-redux';

const MyComponent = () => {
  // Lokalni state
  const [count, setCount] = useState(0);

  // Redux state
  const reduxValue = useSelector(state => state.someValue);
  const dispatch = useDispatch();

  // Memoizacija funkcije kako bi se izbeglo ponovno kreiranje na svakom renderu
  const increment = useCallback(() => {
    setCount(prevCount => prevCount   1);
  }, []);

  // Memoizacija izračunate vrednosti
  const expensiveCalculation = useMemo(() => {
    return count * 2;
  }, [count]);

  // Efekat koji se pokreće samo pri promeni reduxValue
  useEffect(() => {
    console.log("Redux value changed:", reduxValue);
  }, [reduxValue]);

  return (
    

Count: {count}

Expensive Calculation: {expensiveCalculation}

); };

正如我们所看到的,这里使用了本地状态、Redux、memoization 和 useEffect hook 的组合,以使应用程序尽可能高效。

版本声明 本文转载于:https://dev.to/jelena_petkovic/razumevanje-renderovanja-i-rerenderovanja-u-react-aplikacijama-kako-funkcionisu-i-kako-ih-optimizovati-40cj?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 在Pandas中如何将年份和季度列合并为一个周期列?
    在Pandas中如何将年份和季度列合并为一个周期列?
    pandas data frame thing commans date lay neal and pree pree'和pree pree pree”,季度 2000 q2 这个目标是通过组合“年度”和“季度”列来创建一个新列,以获取以下结果: [python中的concate...
    编程 发布于2025-05-19
  • 在Ubuntu/linux上安装mysql-python时,如何修复\“ mysql_config \”错误?
    在Ubuntu/linux上安装mysql-python时,如何修复\“ mysql_config \”错误?
    mysql-python安装错误:“ mysql_config找不到”“ 由于缺少MySQL开发库而出现此错误。解决此问题,建议在Ubuntu上使用该分发的存储库。使用以下命令安装Python-MysqldB: sudo apt-get安装python-mysqldb sudo pip in...
    编程 发布于2025-05-19
  • 如何将MySQL数据库添加到Visual Studio 2012中的数据源对话框中?
    如何将MySQL数据库添加到Visual Studio 2012中的数据源对话框中?
    在Visual Studio 2012 尽管已安装了MySQL Connector v.6.5.4,但无法将MySQL数据库添加到实体框架的“ DataSource对话框”中。为了解决这一问题,至关重要的是要了解MySQL连接器v.6.5.5及以后的6.6.x版本将提供MySQL的官方Visual...
    编程 发布于2025-05-19
  • 如何从PHP中的Unicode字符串中有效地产生对URL友好的sl。
    如何从PHP中的Unicode字符串中有效地产生对URL友好的sl。
    为有效的slug生成首先,该函数用指定的分隔符替换所有非字母或数字字符。此步骤可确保slug遵守URL惯例。随后,它采用ICONV函数将文本简化为us-ascii兼容格式,从而允许更广泛的字符集合兼容性。接下来,该函数使用正则表达式删除了不需要的字符,例如特殊字符和空格。此步骤可确保slug仅包含...
    编程 发布于2025-05-19
  • 如何使用Depimal.parse()中的指数表示法中的数字?
    如何使用Depimal.parse()中的指数表示法中的数字?
    在尝试使用Decimal.parse(“ 1.2345e-02”中的指数符号表示法表示的字符串时,您可能会遇到错误。这是因为默认解析方法无法识别指数符号。 成功解析这样的字符串,您需要明确指定它代表浮点数。您可以使用numbersTyles.Float样式进行此操作,如下所示:[&& && && ...
    编程 发布于2025-05-19
  • 在PHP中如何高效检测空数组?
    在PHP中如何高效检测空数组?
    在PHP 中检查一个空数组可以通过各种方法在PHP中确定一个空数组。如果需要验证任何数组元素的存在,则PHP的松散键入允许对数组本身进行直接评估:一种更严格的方法涉及使用count()函数: if(count(count($ playerList)=== 0){ //列表为空。 } 对...
    编程 发布于2025-05-19
  • 如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    如何为PostgreSQL中的每个唯一标识符有效地检索最后一行?
    postgresql:为每个唯一标识符在postgresql中提取最后一行,您可能需要遇到与数据集合中每个不同标识的信息相关的信息。考虑以下数据:[ 1 2014-02-01 kjkj 在数据集中的每个唯一ID中检索最后一行的信息,您可以在操作员上使用Postgres的有效效率: id dat...
    编程 发布于2025-05-19
  • 为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    为什么PHP的DateTime :: Modify('+1个月')会产生意外的结果?
    使用php dateTime修改月份:发现预期的行为在使用PHP的DateTime类时,添加或减去几个月可能并不总是会产生预期的结果。正如文档所警告的那样,“当心”这些操作的“不像看起来那样直观。 ; $ date->修改('1个月'); //前进1个月 echo $ date->...
    编程 发布于2025-05-19
  • 如何在Chrome中居中选择框文本?
    如何在Chrome中居中选择框文本?
    选择框的文本对齐:局部chrome-inly-ly-ly-lyly solument 您可能希望将文本中心集中在选择框中,以获取优化的原因或提高可访问性。但是,在CSS中的选择元素中手动添加一个文本 - 对属性可能无法正常工作。初始尝试 state)</option> < op...
    编程 发布于2025-05-19
  • `console.log`显示修改后对象值异常的原因
    `console.log`显示修改后对象值异常的原因
    foo = [{id:1},{id:2},{id:3},{id:4},{id:id:5},],]; console.log('foo1',foo,foo.length); foo.splice(2,1); console.log('foo2', foo, foo....
    编程 发布于2025-05-19
  • Java的Map.Entry和SimpleEntry如何简化键值对管理?
    Java的Map.Entry和SimpleEntry如何简化键值对管理?
    A Comprehensive Collection for Value Pairs: Introducing Java's Map.Entry and SimpleEntryIn Java, when defining a collection where each element com...
    编程 发布于2025-05-19
  • 找到最大计数时,如何解决mySQL中的“组函数\”错误的“无效使用”?
    找到最大计数时,如何解决mySQL中的“组函数\”错误的“无效使用”?
    如何在mySQL中使用mySql 检索最大计数,您可能会遇到一个问题,您可能会在尝试使用以下命令:理解错误正确找到由名称列分组的值的最大计数,请使用以下修改后的查询: 计数(*)为c 来自EMP1 按名称组 c desc订购 限制1 查询说明 select语句提取名称列和每个名称...
    编程 发布于2025-05-19
  • C++20 Consteval函数中模板参数能否依赖于函数参数?
    C++20 Consteval函数中模板参数能否依赖于函数参数?
    [ consteval函数和模板参数依赖于函数参数在C 17中,模板参数不能依赖一个函数参数,因为编译器仍然需要对非contexexpr futcoriations contim at contexpr function进行评估。 compile time。 C 20引入恒定函数,必须在编译时进行...
    编程 发布于2025-05-19
  • PHP阵列键值异常:了解07和08的好奇情况
    PHP阵列键值异常:了解07和08的好奇情况
    PHP数组键值问题,使用07&08 在给定数月的数组中,键值07和08呈现令人困惑的行为时,就会出现一个不寻常的问题。运行print_r($月)返回意外结果:键“ 07”丢失,而键“ 08”分配给了9月的值。此问题源于PHP对领先零的解释。当一个数字带有0(例如07或08)的前缀时,PHP将其...
    编程 发布于2025-05-19

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

Copyright© 2022 湘ICP备2022001581号-3