Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >React16的memo函数有啥用

React16的memo函数有啥用

原创
作者头像
挥刀北上
修改于 2020-08-18 10:13:32
修改于 2020-08-18 10:13:32
1.2K00
代码可运行
举报
文章被收录于专栏:Node.js开发Node.js开发
运行总次数:0
代码可运行

React16的memo和PureComponent作用类似,只不过前者只适用于函数组件,后者适应于类组件。

关于两者的作用,我们先从PureComponent说起,在了解PureComponent之前要先了解shouldComponentUpdate函数,在类组件中有一个叫做shouldComponentUpdate的生命周期函数,这个函数可以通过返回true或false来决定当前组件是否重新渲染。

而PureComponent自带shouldComponentUpdate函数,PureComponent自带的shouldComponentUpdate函数会在当前组件的props或者state发生变化时,对props或者state进行浅对比,如果相同则不进行重新渲染,反之则会进行渲染。

说到这里来了解一下浅对比,啥叫浅对比呢,类似于浅拷贝,具体的内容大家可以去百度,这里不做赘述,只做简单说明,举个例子,看代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import React,{memo} from "react";
import ReactDOM from 'react-dom';
class CommentList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      commentList: [{
        body: '大三岁', author: '张三'
      }, {
        body: '新冠病毒', author: '李四'
      }]
    }
  }

  componentWillMount() {
    setTimeout(() => {
      this.setState((prevState, props) => {
        return {
          commentList: [{
            body: '大三岁', author: '张三'
          }, {
              body: '新冠1病毒', author: '李四'
          }]
        }
      })
    }, 1000)
  }

  render() {
    return (
      <div>
        {
          this.state.commentList.map((item, index) => {
            return <Comment {...item} key={index} />
          })
        }
      </div>
    )

  }
}
function Comment(props) {
  console.log('渲染了', props)
  return <div>
    <p>{props.body}</p>
    <p>{props.author}</p>
    <p>{props.arr.length}</p>
  </div>
}

阅读源码,我们定义了两个组件,CommentList组件与Comment组件,CommentList组件内部的state是一个数组,每条数据用Comment来渲染。我们在componentWillMount设置定时器模拟数据发生变化,我们看到第二条数据的body发生变化了,所以对应的comment组件应该重新渲染,但是我们发现所有Comment组件都重新渲染了。这不利于我们页面的性能优化,咋办呢?

此时我们可以借助memo或者PureComponent来实现只让该渲染的组件渲染,啥是该渲染的组件呢?那就是props或者state发生变化的组件,那变化的标准是怎么样的呢?

来看代码,用memo来实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import React,{memo} from "react";
import ReactDOM from 'react-dom';
class CommentList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      commentList: [{
        body: '大三岁', author: '张三' 
      }, {
        body: '新冠病毒', author: '李四' 
      }]
    }
  }

  componentWillMount() {
    setTimeout(() => {
      this.setState((prevState, props) => {
        return {
          commentList: [{
            body: '大三岁', author: '张三'
          }, {
              body: '新冠1病毒', author: '李四'
          }]
        }
      })
    }, 1000)
  }

  render() {
    return (
      <div>
        {
          this.state.commentList.map((item, index) => {
            return <Comment {...item} key={index} />
          })
        }
      </div>
    )

  }
}



function Comment(props) {
  console.log('渲染了', props)
  return <div>
    <p>{props.body}</p>
    <p>{props.author}</p>
    <p>{props.arr.length}</p>
  </div>
}

// 第一种方式 用memo包裹函数组件
Comment = memo(Comment)

用PureComponent来实现:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import React,{memo} from "react";
import ReactDOM from 'react-dom';
class CommentList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      commentList: [{
        body: '大三岁', author: '张三' 
      }, {
        body: '新冠病毒', author: '李四' 
      }]
    }
  }

  componentWillMount() {
    setTimeout(() => {
      this.setState((prevState, props) => {
        return {
          commentList: [{
            body: '大三岁', author: '张三'
          }, {
              body: '新冠1病毒', author: '李四'
          }]
        }
      })
    }, 1000)
  }

  render() {
    return (
      <div>
        {
          this.state.commentList.map((item, index) => {
            return <Comment {...item} key={index} />
          })
        }
      </div>
    )

  }
}

class Comment extends React.PureComponent {
  constructor() {
    super()
  }
  render() {
    console.log('渲染了')
    const props = this.props
    return <div>
      <p>{props.body}</p>
      <p>{props.author}</p>
    </div>
  }
}

阅读源码,我们分别用memo和PureComponent改造了代码,并且运行的话,只有该渲染的组件发生了渲染。

渲染的组件前后的props发生变化的组件才会重新渲染,来看一下props或者state发生变化的标准:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{body: '新冠病毒', author: '李四'} 

{body: '新冠1病毒', author: '李四'} 

上面两个对象进行浅对比body发生变化,所以会渲染,而另一个组件数据没变所以没有重新渲染,从而提高了页面性能。

以上便是memo的作用了,但是这里有一个问题,那就是如果props中的某一个属性是引用数据类型,这个引用数据发生改变,但是引用未变,组件是不会重新渲染的,首先我们看下不使用memo的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import React,{memo} from "react";
import ReactDOM from 'react-dom';
class CommentList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      commentList: [{
        body: '大三岁', author: '张三',arr:[]
      }, {
        body: '新冠病毒', author: '李四',arr:[]
      }]
    }
  }

  componentWillMount() {
    setTimeout(() => {
      this.state.commentList[0].arr.push(999)
      this.setState({ commentList: this.state.commentList})
    }, 1000)
  }

  render() {
    return (
      <div>
        {
          this.state.commentList.map((item, index) => {
            return <Comment {...item} key={index} />
          })
        }
      </div>
    )

  }
}

// 

function Comment(props) {
  console.log('渲染了', props)
  return <div>
    <p>{props.body}</p>
    <p>{props.author}</p>
    <p>{props.arr.length}</p>
  </div>
}

上面的代码,我们没有使用memo,Comment的props发生变化后,所有的Comment组件都重新渲染了,如图:

效果截图
效果截图

上图红框处显示了组件重新渲染了,然后我们用memo改造代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import React,{memo} from "react";
import ReactDOM from 'react-dom';
class CommentList extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      commentList: [{
        body: '大三岁', author: '张三',arr:[]
      }, {
        body: '新冠病毒', author: '李四',arr:[]
      }]
    }
  }

  componentWillMount() {
    setTimeout(() => {
      this.state.commentList[0].arr.push(999)
      this.setState({ commentList: this.state.commentList})
    }, 1000)
  }

  render() {
    return (
      <div>
        {
          this.state.commentList.map((item, index) => {
            return <Comment {...item} key={index} />
          })
        }
      </div>
    )

  }
}

// 

function Comment(props) {
  console.log('渲染了', props)
  return <div>
    <p>{props.body}</p>
    <p>{props.author}</p>
    <p>{props.arr.length}</p>
  </div>
}


Comment = memo(Comment)

此时看效果:

效果截图
效果截图

上图展示显示了,虽然组件的props发生了变化,但是组件为重新渲染。

那这个bug怎么解决呢,很简单,不要直接修改完数据直接使用,而是修改完后深拷贝一下再去调用setState。

所以在使用memo和PureComponent时大家需要特别注意,总结一下:

1、memo和PureComponent的作用提高渲染性能,避免不必要的渲染。

2、memo和PureComponent的原理是通过浅拷贝来实现的。

3、通过案例演示了memo的作用。

4、memo的缺点,当props或state中的属性有引用属性时需要注意,修改完成后进行一下深拷贝在调用setState。

以上便是使用memo的一下注意事项,希望对你有所帮助。

参考:你真的了解浅比较么?

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
MongoDB教程(十一):MongoDB关系管理与文档关联
💝💝💝首先,欢迎各位来到我的博客,很高兴能够在这里和您见面!希望您在这里不仅可以有所收获,同时也能感受到一份轻松欢乐的氛围,祝你生活愉快!
用户11147438
2024/07/20
1360
MongoDB的特点和优势
MongoDB是一个基于分布式文件存储的NoSQL数据库,它是当前最流行的NoSQL数据库之一。MongoDB具有很多优点和特点,使其成为了一种非常受欢迎的数据库选择。下面将详细介绍MongoDB的特点和优势,并给出一些示例。
玖叁叁
2023/04/13
2K0
MongoDB: 介绍
在当今互联网时代,数据是任何应用的核心。为了更有效地存储和检索数据,许多开发者和组织转向了NoSQL数据库,其中MongoDB是一个备受关注的解决方案。MongoDB是一个开源的文档型数据库,以其灵活性、可扩展性和高性能而闻名。本文将介绍MongoDB的使用、原理以及其在现代应用程序中的角色。
Michel_Rolle
2023/12/15
3K0
MongoDB系列之什么是非关系型数据库
NoSQL,指的是非关系型的数据库。NoSQL是Not Only SQL的缩写,是对不同于传统的关系型数据库管理系统的统称。非关系型数据库不同于传统的关系型数据库,非关系型数据库对数据的存储不需要特定的模式,适用于大规模的数据存储。
SmileNicky
2022/06/14
8890
MongoDB系列之什么是非关系型数据库
NoSql非关系型数据库
参考blog:http://blog.csdn.net/u012377333/article/details/50598519
洋仔聊编程
2019/01/15
3.8K0
HBase与传统关系型数据库的区别是什么?
HBase与传统关系型数据库在数据模型、数据存储方式和适用场景等方面存在一些区别。下面将通过一个具体的案例来讲解HBase与传统关系型数据库的区别,并提供详细的代码示例和注释。
GeekLiHua
2025/01/21
1690
什么是关系型数据库?
关系型数据库(RDBMS)是建立在关系模型基础上的数据库系统。关系模型是一种数据模型,它表示数据之间的联系,包括一对一、一对多和多对多的关系。在关系型数据库中,数据以表格的形式存储,每个表格称为一个“关系”,每个关系由行(记录或元组)和列(字段或属性)组成。
人不走空
2024/02/20
6170
非关系型数据库(NOSQL)和关系型数据库(SQL)区别详解
https://baike.baidu.com/item/%E5%85%B3%E7%B3%BB%E6%95%B0%E6%8D%AE%E5%BA%93%E7%B3%BB%E7%BB%9F
追逐时光者
2021/02/03
44.2K0
IT入门知识第四部分《数据库》(4/10)
在数字化时代,数据无处不在,而数据库则是组织和管理这些数据的系统。数据库不仅为企业提供了数据存储的解决方案,还使得数据的检索、分析和处理变得更加高效和系统化。
正在走向自律
2024/12/18
2290
IT入门知识第四部分《数据库》(4/10)
关系型数据库和非关系型数据库
事务,是指一个操作序列,这些操作要么都执行,或者都不执行,而且这一序列是无法分隔的独立操作单位。也就是符合原子性(Atomicity)、 一致性(Consistency)、 隔离性(Isolation)和持久性(Durability)的一组操作。
归思君
2023/10/16
9600
关系型数据库和非关系型数据库
文档型数据库MongoDB的安装与入门操作
MongoDB作为NoSql数据库中的典型代表,在分布式项目中广泛应用于存储格式灵活的JSON类型数据。在笔者的上一篇文章重点推荐一个基于SpringCloud的电商微服务项目mall-swarm的微服务项目中也用到了MongoDB, 因此为了深入学习这个微服务项目,咱们有必要对MongoDB有个入门的学习。至少得在自己的电脑或者服务器上安装好MongoDB服务,并学会一些基本的CRUD操作。本文笔者就来领大家学会Windows和Linux环境下安装最新稳定版本的MongDB 6.0.2版本服务,并使用学会一些基本的CRUD shell命令操作。
用户3587585
2022/11/29
4.3K0
文档型数据库MongoDB的安装与入门操作
关系型数据库与非关系型数据库
  当前我们各种高并发的时代下,NoSql正以大规模侵袭的状态下入侵SQL界,我们现在很普及的关系数据库如mysql、oracle、DB2、Microsoft的SQL Server等
haoming1100
2019/02/15
5.1K0
python-数据库编程-SQL的基础语法和命令
SQL是Structured Query Language(结构化查询语言)的缩写。它是一种用于关系型数据库管理系统(RDBMS)的编程语言。SQL使用各种命令来创建,修改和查询数据库。
玖叁叁
2023/04/22
4860
关系型数据库和非关系型数据
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
chenchenchen
2019/09/02
6.9K0
关系型数据库和非关系型数据
基本 nosql 和 mongodb等数据库对比基本 nosql 和 mongodb等数据库对比
咱们工作或者学习的过程中,接到一个需求,或者学习一个技能的时候,我们是如何去学习的呢?
阿兵云原生
2023/02/16
7850
【Java 进阶篇】MySQL数据库范式详解
范式是数据库设计中的一种理论方法,旨在通过减少数据冗余来提高数据存储的有效性和完整性。在MySQL数据库中,范式设计是一个重要的概念,它有助于组织和管理数据,确保数据的一致性和可靠性。本文将深入探讨数据库范式,包括不同范式的概念、优缺点以及示例代码。
繁依Fanyi
2023/10/12
2860
【Java 进阶篇】MySQL数据库范式详解
Golang语言社区--【数据库知识】从关系型数据库到非关系型数据库
1. 关系型数据库 关系型数据库,是指采用了关系模型来组织数据的数据库。 关系模型是在1970年由IBM的研究员E.F.Codd博士首先提出的,在之后的几十年中,关系模型的概念得到了充分的发展并逐渐成为主流数据库结构的主流模型。 简单来说,关系模型指的就是二维表格模型,而一个关系型数据库就是由二维表及其之间的联系所组成的一个数据组织。 关系模型中常用的概念: 关系:可以理解为一张二维表,每个关系都具有一个关系名,就是通常说的表名 元组:可以理解为二维表中的一行,在数据库中经常被称为记录 属性:可以理解为二维
李海彬
2018/03/21
2.7K0
什么是关系型数据库和非关系型数据库
应用程序都离不开数据库,那不同的数据结构,就会存放在不同的数据数据库中,所以数据库按数据结构分为关系型数据库和非关系型数据库。接下来就总结一下这两者的区别吧。
小冷coding
2023/05/25
2.6K0
什么是关系型数据库和非关系型数据库
NoSQL 之于大数据
关系型数据库几乎是许多开发者和DBA对于传统三层架构应用的唯一选择。使用这一场景有很多原因,数据建模方法,查询语言与数据交互,保证数据的一致性部署,并能够为复杂的应用服务。
半吊子全栈工匠
2018/08/22
4880
NoSQL 之于大数据
【独家】一文读懂非关系型数据库(NoSQL)
本文共11000字,阅读全文约需30分钟。 本文为大家解析非关系型数据库(NoSQL)。[ 在数据派THU后台(非留言区)回复"综述"即可获取资源。] 前言 NoSQL(NoSQL = Not Only SQL ),意即"不仅仅是SQL"。 现代计算系统每天在网络上都会产生庞大的数据量。这些数据有很大一部分是由关系型数据库管理系统(RDBMSs)来处理,其严谨成熟的数学理论基础使得数据建模和应用程序编程更加简单。 但随着信息化的浪潮和互联网的兴起,传统的RDBMS在一些业务上开始出现问题。首先,对数
数据派THU
2018/01/29
10.8K0
推荐阅读
相关推荐
MongoDB教程(十一):MongoDB关系管理与文档关联
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验