react性能优化之memo的作用和memo的坑
前言
在react中,组件渲染的是最常有的事情。但是,有部分的渲染是不必要的,是可以避免的。
在react的一般规则中,只有父组件的某一个状态改变,父组件下面所有的子组件不论是否使用了该状态,都会进行重新渲染。
显然,对于没有用到被改变的那个状态的组件来说,重新渲染是完全没有必要的。所以,React.memo就诞生了。
父组件中状态的改变会让所有的子组件重新渲染
举个例子 ↓
上面的例子中,我们有两个state,一个buibuibui,一个tututu。被传入children组件的是tututu,在父组件中改变的是buibuibui。
问:当父组件的buibuibui这个state被改变的时候,只接收了tututu这个变量的children(子组件)会被重新渲染吗。
答:会的,只要父组件的状态改变,所有的子组件不论是否使用到了被改变的那个state都会被重新渲染。
如图↓
显然这种渲染是完全没必要的。我又没有使用被改变的那个state,我本身本身也没有什么视图需要更新,根本没必要重新渲染。
在阻止重新渲染这个需求的基础上,诞生了memo(),memo是react的一种缓存技术,这个函数可以检测从父组件接收的props,并且在父组件改变state的时候比对这个state是否是本组件在使用,如果不是,则拒绝重新渲染。
memo 和它的使用方式
并且它的使用方法也非常的简单。只需要在把子组件当成这个函数的入参包起来就好了。
例如↓
像这样,这Children就是被缓存成功了。下次当父组件中无关它的state(状态)被更新时候,Children组件就不会重新渲染。
参考上面的例子去介绍memo()就是
子组件被memo函数保护了。当父组件中一切无关子组件的state被改变时,子组件拒绝重新渲染,这样节省了性能。
而上面的例子中,传入Children组件的是tututu这个状态。而父组件中被改变的是buibuibui这个state。buibuibui被改变与Children无关,因为children被memo保护,所以chidren不重新渲染。
反之,如果children组件没有被memo保护,那么即使被改变的buibuibui这个state与children组件无关。children组件也会被重新渲染。
总而言之就是,如果当前组件被memo保护,那么当前组件的props不变,则组件不进行重新渲染。这样,我们合理的使用memo就可以为我们的项目带来很大的性能优化。
以上,就是关于react的组价缓存。
memo的坑
上面说了memo的用处和好处。
下面我们来说memo坑的地方
第一个坑
有那么一种情况,被memo的保护的组件即使props变了,它也不会重新渲染。
当被改变的那个props是一个数组(对象)的时候
例如↓
上图中,传入了一个list数组进去子组件,子组件内部是被memo缓存了的。这个时候,如果我们往list这个数组中push()一个6,那么子组件中的props改变了,理论上来说,子组件应该重新渲染了。但实际上并不会。
这是为什么呢?因为memo的保护是对props做一个浅比较(不了解什么是浅比较的同学点这里)
而数组的使用push()方法看似是变了。但变的只是堆中的数据,存在与栈中的地址依然不会改变。memo是检测不到的。所以,使用push等不能返回一个新数组的方法,均无法触发memo的更新机制。
如图↓
想要改变数组也能让子组件更新,有方法。
就像刚刚说的,需要让memo检测到数组栈地址的变化。要栈地址变化的话,只要返回一个全新的数组就好了。
所以,我们不妨将代码做出以下修改。
const [list,setList] = useState([1,2,3,4,5]);setList(list.push(1)); //这样是不会被memo检测到的,是无法触发memo更新的setList([...list,1]); //这样才可以,创建一个新数组,再在里面解构旧数组,往后面追加 1//这样,就等于返回了一个新的数组,栈中的地址就会改变,memo就可以检测到并触发更新
这样,就可以既修改数组,又触发组件更新了
第二个坑
对!还有第二个坑!!
memo是不是很好用?是不是有那么好的东西恨不得每个组件都包一下?
这就是它坑的地方了,它不能每个组件都包一下。
倒不是说全包就报错,只是如果全包的话,还不如不包。
话说回来,如果真的每个组件都有被缓存的必要而且不会给项目带来破坏性问题,为什么react不直接把memo设为默认的呢。当然是因为每个都缓存的话,会给项目带来毁灭性的问题咯。
我们需要知道的是,缓存也需要成本。如果每个组件都进行缓存,会给浏览器带来非常非常大的负担。
所以在平常项目中,我们需要挑选一些经常被使用,经常会被重新渲染的组件去有目标的缓存他。而不是每一个组件都缓存一下。切记切记。
总结
- 父组件中state(状态)改变,不受memo保护的子组件也会重新渲染
- memo会检测props到改变来决定组件是否需要进行重新渲染,换言之就是,被memo函数包起来的组件只有本身的props被改变之后才会重新渲染
- memo只能进行浅拷贝来校验决定是否触发重新渲染。所以改变数组(对象)的props时候记得返回一个全新的数组(对象)
- memo不是项目中所有的组件都需要包一下。包的太多反而会起反效果,我们需要选择那些经常被重新渲染的组件有选择性的去缓存。
react性能优化之memo的作用和memo的坑相关推荐
- React性能优化SCU | PureComponent | memo
文章目录 React性能优化SCU React更新机制 render函数被调用 PureComponent 高阶组件memo React性能优化SCU React更新机制 我们在前面文章已经讲解过Re ...
- react性能优化方案_React灵敏且性能卓越的Spray + Akka解决方案,以“在Java和Node.js中发挥并发性和性能”...
react性能优化方案 在我以前的文章中,我研究了一个虚拟的交易引擎,并将基于Java的阻止解决方案与基于Node.js的非阻止解决方案进行了比较. 在文章的结尾,我写道: 我怀疑随着Node.js的 ...
- [react] 你知道的react性能优化有哪些方法?
[react] 你知道的react性能优化有哪些方法? shouldComponentUpdate PureComponent :Class Component React.Memo :Functio ...
- React性能优化(完整版)
我的博客 http://wangxince.site/my-demo-markdown/ React 性能优化 1.减少 render 次数 shouldComponentUpdate PureCom ...
- React性能优化记录(不定期更新)
React性能优化记录(不定期更新) 1. 使用PureComponent代替Component 在新建组件的时候需要继承Component会用到以下代码 import React,{Componen ...
- Airbnb 爱彼迎房源详情页中的 React 性能优化
Airbnb 爱彼迎工程师和数据科学家将定期和大家分享移动开发.系统架构.数据科学及人工智能等领域的技术探索和经验心得. 正文从这开始-- 在一些容易被忽视但又非常重要的场景,可能会有许多严重影响性能 ...
- 深入学习React函数组件性能优化三剑客useMemo、useCallback、memo
Hook使用规则 只能在函数的最外层调用Hook,不能在循环.条件判断或子函数中调用. 只能在React函数组件或自定义Hook中调用Hook,不可在其他JavaScript函数中使用. useMem ...
- react 组件遍历】_从 Context 源码实现谈 React 性能优化
(给前端大全加星标,提升前端技能) 转自:魔术师卡颂 学完这篇文章,你会收获: 了解Context的实现原理 源码层面掌握React组件的render时机,从而写出高性能的React组件 源码层面了解 ...
- React 性能优化完全指南,将自己这几年的心血总结成这篇!
作者: MoonBall 原文地址: https://juejin.cn/post/6935584878071119885 本文分为三部分,首先介绍 React 的工作流,让读者对 React 组件更 ...
最新文章
- 把时间当作朋友(第一版)笔记
- Attention最新进展
- iphone导出照片到电脑_如何更改 iPhone 照片格式?
- Please ensure JDK installation is valid and compatible with the current OS
- linq to sql简单使用
- vue 新窗口打开外链接
- 机房管理系列之杀毒服务器维护
- 加密数据的检索_透明地持久保存并从数据库中检索加密的数据
- C# DllImport的用法(转)
- 中文词向量论文综述(三)
- MySQL中文参考手册--8.MySQL教程--8.3 常用查询的例子
- 5G注册流程分级详解
- 我爱高圆圆 键盘录入数据,模拟单项选择题
- ISTQB认证-关于ISTQB一些知识点总结
- mcreator安装教程
- sýnesis™ Lite for Snort provides basic analytics for Snort IDS/IPS alert logs using the Elastic Stac
- 早安我的少年怎么用电脑玩 早安我的少年模拟器玩法教程
- 在20岁到30岁的约定
- 打车软件被勒令叫停的背后
- 从平安普惠捆绑意外险,看最强金融生存法则:底子厚、路子野、扛得住