iis服务器助手广告广告
返回顶部
首页 > 资讯 > 数据库 >React中immutable的使用
  • 195
分享到

React中immutable的使用

Reactimmutable 2023-04-19 05:04:08 195人浏览 八月长安
摘要

目录UI组件渲染性能方案一:shallow compare总结:React 一直遵循UI = fn(state) 的原则,有时候我们的state却和UI不同步 有时候组件本身在业务上不需要渲染,却又会再一次re-rend

React 一直遵循UI = fn(state) 的原则,有时候我们的state却和UI不同步 有时候组件本身在业务上不需要渲染,却又会再一次re-render。之前在项目中遇到的一些问题,这里做一个简单的分析,大家可以一起交流一下

UI组件渲染性能

react每次触发页面的更新可大致分成两步:

  • render(): 主要是计算v-dom的diff
  • commit阶段 :将得到的diff v-dom一次性更新到真实DOM

一般我们讨论的渲染 指的是第一步, 我可以悄悄的告诉你 第二步我们也管不了,什么时候更新真实DOM, React有一套自己的机制

组件渲染分为首次渲染和重渲染,首次渲染不可避免就不讨论 重渲染指当组件state或者props发生变化的时候造成的后续渲染过程,也是本文的讨论重点

其实React 在更新组件这方面 一直都有一个诟病 就是:

父组件重渲染的时候,会递归重渲染所有的子组件

const List = () => {
  const [name, setName] = useState<string>("");
  // 用来测试的其它状态值
  const [count, setCount] = useState<number>(0);
  const handleInputChange = (e: React.ChangeEvent<htmlInputElement>) => {
    const val = e.target.value;
    setName(val);
  };
  const handleClick = () => {
    setCount((c) => c + 1);
  };
  return (
    <main>
      <div className="list">
        <input value={name} onChange={handleInputChange} />
        <button onClick={handleClick}>测试</button>
        <Child count={count} />
      </div>
    </main>
  );
};
const Child: React.FC<any> = (props) => {
  console.log("Child has render");
  return <p>count:{props.count}</p>;
};

React中immutable的使用

当 Input name改变的时候 List触发rerender Child会发生rerender 可是Child 依赖的props只有count而已, 如果所有的子组件都被迫渲染,计算在render花费的时间和资源有可能成为性能瓶颈.

方案一:shallow compare

React其实刚出来就提供了优化的手段:

  • shouldComponentUpdate: 返回false 就直接跳过组件的render过程
  • React.PureComponent: 对props进行浅比较,如果相等 则跳过render 用于class 组件
  • React.memo: 也是进行浅比较,适用于functional Component

本文设计的组件以functioal component为主 因为后面会涉及到hooks的使用,对上述例子修改:

const Child: React.FC<any> = React.memo((props) => {
  console.log("Child has render");
  return <p>count:{props.count}</p>;
}) 

React中immutable的使用

很好 child没有跟着name重渲染了,如果props是一个对象呢?

const List = () => {
  const [name, setName] = useState<string>("");
  // 用来测试的其它状态值
  const [count, setCount] = useState<number>(0);
  console.log(count)
  const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
    const val = e.target.value;
    setName(val);
  };
  const handleClick = () => {
    setCount((c) => c + 1);
  };
  const item: IItem = {
    text: name,
    id: 1,
  };
  return (
    <main>
      <div className="list">
        <input value={name} onChange={handleInputChange} />
        <button onClick={handleClick}>测试</button>
        <Child  item={item} />
      </div>
    </main>
  );
};
const Child: React.FC<{ count?: number; item: IItem }> = React.memo(
  ({ item }) => {
    console.log("Child has render");
    return <p>text:{item.text}</p>;
  }
);

改变name时候Child会改变 这是预期内的 而当改变count时,Child还是会重渲染,这是什么原因呢?因为count改变后 List组件会rerender 从而导致导致 item这个对象又重新生成了 导致child每次接受的是一个新的object对象 由于每个literal object的比较是引用比较 虽然前后属性相同,但比较得出的结果为false,造成 Child rerender 。

浅比较一定要相同引用吗?不一定,一般的面试中浅比较只是对值的比较 但是React.memo中要求引用类型一定要相同 为什么呢?我猜是出于对性能的考虑,不用深比较也是为了节约性能 通常情况下 我们想要的UI对应的是每个叶子节点的值 ,即只要叶子节点的值不发生变化 就不要rerender

方案:

  • 直接对前后的对象进行deepCompare

还好React.memo有第二个参数可以使用

const Child: React.FC<{ item: IItem }> = React.memo(
  ({ item }) => {
    console.log("Child has render");
    return <p>text:{item.text}</p>;
  },
  (preProps, nextProps) => {
    return _.isEqual(preProps, nextProps); // lodash的深比较 
  }
);
  • 保证引用相等的情况下,值也相等 useRef
  const item: MutableRefObject<IItem> = React.useRef({
    text: name,
    id: 1,
  });
<Child item={item.current} />

好家伙,name无论怎么变化 Child 始终不会更新,useRef保证了返回的值是一个MutableObject 不可变的,意思就是引用完全相同 不管值变化 就不会保持更新.导致了UI不一致,那么我们怎么保证 name 不变的时候 item 和上次相等,name 改变的时候才和上次不等。useMemo

  const item: IItem = React.useMemo(
    () => ({
      text: name,
      id: 1,
    }),
    [name] // name变化触发item不等 name不变item和上次相同
  );

总结:

  • 父组件重渲染的时候,会递归重渲染所有的子组件
  • 对primitive 值的数据 React比较值的相等来判断是否重渲染组件 对Object数据 React比较引用 如果引用相同 不会重渲染,如果引用不同 会认为是不同对象 造成重渲染
  • useRef返回一个MutableRefObject数据 永远返回的是同一个引用 直到生命周期结束,官网的注解
  • useRef returns a mutable ref object whose .current property is initialized to the passed argument
    • (initialValue). The returned object will persist for the full lifetime of the component.
  • useMemo 返回一个计算的值 当dep改变时 返回的值才改变(引用的改变)

到此这篇关于React中immutable的使用的文章就介绍到这了,更多相关React immutable内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

您可能感兴趣的文档:

--结束END--

本文标题: React中immutable的使用

本文链接: https://www.lsjlt.com/news/201629.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • React中immutable的使用
    目录UI组件渲染性能方案一:shallow compare总结:react 一直遵循UI = fn(state) 的原则,有时候我们的state却和UI不同步 有时候组件本身在业务上不需要渲染,却又会再一次re-rend...
    99+
    2023-04-19
    React immutable
  • react中使用antd及immutable示例详解
    目录一、react中使用antd组件库二、Immutable2.1 深拷贝和浅拷贝的关系2.2 immutable优化性能方式2.3 immutable的Map使用2.4 immut...
    99+
    2022-11-13
    react使用antd immutable react antd react immutable
  • React Immutable使用方法详细介绍
    目录1. 介绍2. 优缺点3. 对象处理4. 数组处理5. 优化组件渲染6. immutable和redux集合使用1. 介绍 假设当前 redux 的大小为 1G,现在要修改 re...
    99+
    2022-11-13
  • React替换传统拷贝方法的Immutable使用
    目录immutable安装使用Map嵌套MapList实现个人修改案例immutable 它是一款代替传统拷贝方式的第三方库 优势: 在新对象上操作不会影响原对象的数据性能好 安装使...
    99+
    2023-02-06
    React Immutable React Immutable使用
  • React中immutable的UI组件渲染性能详解
    目录引言UI组件渲染性能方案一:shallow compare方案二:直接对前后的对象进行deepCompare总结:引言 react 一直遵循UI = fn(state) 的原则,...
    99+
    2023-05-16
    React immutable UI组件渲染 React UI组件渲染
  • React项目中使用Redux的 react-redux
    目录背景UI 组件容器组件connect()mapStateToProps()mapDispatchToProps()组件实例:计数器背景 在前面文章一文理解Redux及其工作原理中...
    99+
    2022-11-13
  • React html中使用react的两种方式
    基本使用 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8...
    99+
    2022-11-12
  • React中使用react-file-viewer问题
    目录使用react-file-viewerreact-file-viewer预览本地文件解决思路使用react-file-viewer 1.npm install react-fil...
    99+
    2022-11-13
  • react如何在React html中使用
    本篇文章为大家展示了react如何在React html中使用,内容简明扼要并且容易理解,绝对能使你眼前一亮,通过这篇文章的详细介绍希望你能有所收获。基本使用<!DOCTYPE html><html l...
    99+
    2023-06-14
  • React中styled-components的使用
    目录一、官网地址二、styled-components三、基本使用四、全局默认样式引入五、传参六、继承七、修改组件内部标签八、定义组件属性九、背景图片引入十、塑造组件十一、动画```...
    99+
    2022-11-13
  • React 中使用 react-i18next 国际化的过程(react-i18next 的基本用法)
    目录简介安装与使用安装准备新建一个 React 项目,安装依赖包;使用检测当前浏览器语言国际化组件手动切换国际化语言总结本文使用 React-i18next 库结合 React, 介...
    99+
    2023-01-06
    React 使用 react-i18next 国际化 react i18next 国际化 react-i18next
  • React中使用Mobx的方法
    目录一、Mobx前端状态管理框架 基础概念?1. 什么是Mobx2. 什么是状态管理?3. 为什么需要状态管理?状态管理的一般思想(Flux)二、mobx的用法1. 安装 mobx2...
    99+
    2023-02-03
    React使用Mobx React使用Mobx
  • react中的key怎么使用
    这篇“react中的key怎么使用”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“react...
    99+
    2022-10-19
  • React中useRef的具体使用
    相信有过React使用经验的人对ref都会熟悉,它可以用来获取组件实例对象或者是DOM对象。 而useRef这个hooks函数,除了传统的用法之外,它还可以“跨渲染周期”保存数据。 ...
    99+
    2022-11-12
  • React中的css如何使用
    这篇文章主要介绍了React中的css如何使用的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇React中的css如何使用文章都会有所收获,下面我们一起来看看吧。一、行内样式使用import React...
    99+
    2023-06-27
  • react中的useMemo怎么使用
    今天小编给大家分享一下react中的useMemo怎么使用的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。概念react 中是...
    99+
    2023-07-04
  • React中的ref怎么使用
    这篇文章主要介绍“React中的ref怎么使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“React中的ref怎么使用”文章能帮助大家解决问题。1. ref 的理解与使用对于 Ref 的理解,要从...
    99+
    2023-07-04
  • react中的mobx如何使用
    这篇文章主要介绍“react中的mobx如何使用”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“react中的mobx如何使用”文章能帮助大家解决问题。新建一个mobx.jsx文件import&nbs...
    99+
    2023-07-06
  • react国际化react-intl的使用
    react怎么实现国际化?react-intl插件提供了一套实现react国际化的方法,具体实现如下~~ 一 搭建react环境和下载相应插件 默认你已经安装了nodejs 如果没有...
    99+
    2022-11-12
  • React-hooks中的useEffect使用步骤
    目录1.理解函数副作用什么是副作用常见的副作用2.基础使用使用步骤示例代码3.依赖项控制useEffect 永远是在 DOM渲染完成之后执行 1.理解函数副作用 什么是副作用 对于R...
    99+
    2022-11-13
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作