React优化子组件render的使用


Posted in Javascript onMay 12, 2019

在react中,父组件的重新render会引发子组件的重新render,但是一些情况下我们会觉得这样做有些多余,比如:

  1. 父组件并未传递props给子组件
  2. 新传递的props渲染结果不变
class A extends React.Component {
  render() {
    console.log('render')
    return <div>这是A组件</div>
  }
}

class Main extends React.Component {
  render() {
    return (
      <div>
        // 点击button会让A不断调用render
        <button onClick={() => this.setState({ a: 1 })}>Main</button>
        <A />
      </div>
    )
  }
}

为了解决这个问题,需要分为ES6类组件和函数式组件两种:

类组件

使用shouldComponentUpdate来对props和state进行判断以此决定是否进行render

class A extends React.Component {
  shouldComponentUpdate(nextProps, nextState) {
    //两次props对比
    return nextProps.a === this.props.a ? false : true
  }
  render() {
    console.log('render')
    return <div>这是A组件</div>
  }
}

class Main extends React.Component {
  // ...
  render() {
    return (
      <div>
        <button onClick={() => this.setState({ a: 1 })}>Main</button>
        <A a={this.state.a} />
      </div>
    )
  }
}

通过返回false来跳过这次更新

使用React.PureComponent,它与React.Component区别在于它已经内置了shouldComponentUpdate来对props和state进行浅对比,并跳过更新

//PureComponent
class A extends React.PureComponent {
  render() {
    console.log('render')
    return <div>这是A组件</div>
  }
}

class Main extends React.Component {
  state = {
    a: 1
  }
  render() {
    return (
      <div>
        <button onClick={() => this.setState({ a: 1 })}>Main</button>
        <A a={this.state.a} />
      </div>
    )
  }
}

函数组件

使用高阶组件React.memo来包裹函数式组件,它和类组件的PureComponent类似,也是对对props进行浅比较决定是否更新

const A = props => {
  console.log('render A')
  return <div>这是A组件</div>
}
// React.memo包裹A
const B = React.memo(A)

const Main = props => {
  const [a, setA] = useState(1)
  console.log('render Main')

  return (
    <div>
      // 通过setA(a + 1)让父组件重新render
      <button onClick={() => setA(a + 1)}>Main</button>
      // 一直传入相同的props不会让子组件重新render
      <B a={1} />
    </div>
  )
}

它的第二个参数接受一个两次props作为参数的函数,返回true则禁止子组件更新

其他

上面提到的浅比较就是根据内存地址判断是否相同:

// extends React.Component
class A extends React.Component {
  render() {
    console.log('render A')
    console.log(this.props)
    return <div>这是组件A</div>
  }
}

class Main extends React.Component {
  test = [1, 2, 3]
  render() {
    console.log('render Main')
    return (
      <div>
        <button
          onClick={() => {
            // 父组件render
            this.setState({})
            this.test.push(4)
          }}
        >
          Main
        </button>
        <A test={this.test} />
      </div>
    )
  }
}

结果是:

使用React.component:

React优化子组件render的使用

使用React.PureComponent:

React优化子组件render的使用

使用React.component,点击之后子组件重新render。改为React.PureComponent之后,点击button子组件并不会render。也因此,PureComponent根据前后内存地址判断是否相等,所以向子组件传递函数作为props时,使用内联箭头函数的形式将会导致子组件的重新render;所以可以用箭头函数作为成员变量的形式再将函数引用作为props传递。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
用JS实现一个TreeMenu效果分享
Aug 28 Javascript
JavaScript 5 新增 Array 方法实现介绍
Feb 06 Javascript
javascript中节点的最近的相关节点访问方法
Mar 20 Javascript
JS中引用百度地图并将百度地图的logo和信息去掉
Sep 29 Javascript
动态加载JS文件的三种方法
Nov 08 Javascript
js判断设备是否为PC并调整图片大小
Feb 12 Javascript
自己动手制作基于jQuery的Web页面加载进度条插件
Jun 03 Javascript
基于LayUI分页和LayUI laypage分页的使用示例
Aug 02 Javascript
XMLHttpRequest对象_Ajax异步请求重点(推荐)
Sep 28 Javascript
浅谈vue 单文件探索
Sep 05 Javascript
vue插槽slot的理解和使用方法
Apr 03 Javascript
vue路由权限校验功能的实现代码
Jun 07 Javascript
基于elementUI使用v-model实现经纬度输入的vue组件
May 12 #Javascript
vue组件中watch props根据v-if动态判断并挂载DOM的问题
May 12 #Javascript
用js简单提供增删改查接口
May 12 #Javascript
electron-vue利用webpack打包实现多页面的入口文件问题
May 12 #Javascript
vue中axios实现数据交互与跨域问题
May 12 #Javascript
jquery3和layui冲突导致使用layui.layer.full弹出全屏iframe窗口时高度152px问题
May 12 #jQuery
JS块级作用域和私有变量实例分析
May 11 #Javascript
You might like
ADODB的数据库封包程序库
2006/12/31 PHP
php模拟用户自动在qq空间发表文章的方法
2015/01/07 PHP
php实现的双色球算法示例
2017/06/20 PHP
PHP实现的自定义图像居中裁剪函数示例【测试可用】
2017/08/11 PHP
PHP数组常用函数实例小结
2018/08/20 PHP
JavaScript与函数式编程解释
2007/04/27 Javascript
jquery图片延迟加载 前端开发技能必备系列
2012/06/18 Javascript
两个数组去重的JS代码
2013/12/04 Javascript
require简单实现单页应用程序(SPA)
2016/07/12 Javascript
js中判断变量类型函数typeof的用法总结
2016/08/09 Javascript
jquery中$.fn和图片滚动效果实现的必备知识总结
2017/04/21 jQuery
微信小程序调用摄像头隐藏式拍照功能
2018/08/22 Javascript
浅谈从React渲染流程分析Diff算法
2018/09/08 Javascript
解决vuejs项目里css引用背景图片不能显示的问题
2018/09/13 Javascript
详解小程序循环require之坑
2019/03/08 Javascript
微信小程序结合Storage实现搜索历史效果
2019/05/18 Javascript
[02:27]DOTA2英雄基础教程 莱恩
2014/01/17 DOTA
[48:30]LGD vs infamous Supermajor小组赛D组 BO3 第一场 6.3
2018/06/04 DOTA
Python使用pandas处理CSV文件的实例讲解
2018/06/22 Python
python利用requests库进行接口测试的方法详解
2018/07/06 Python
对python3新增的byte类型详解
2018/12/04 Python
python 图像平移和旋转的实例
2019/01/10 Python
python实现ftp文件传输功能
2020/03/20 Python
完美解决pycharm 不显示代码提示问题
2020/06/02 Python
CSS3用@font-face实现自定义英文字体
2013/09/23 HTML / CSS
如何用H5实现一个触屏版的轮播器的实例
2017/01/09 HTML / CSS
英国计算机产品零售商:Novatech(定制个人电脑、笔记本电脑、工作站和服务器)
2018/01/28 全球购物
KIEHL’S科颜氏官方旗舰店:源自美国的顶级护肤品牌
2018/06/07 全球购物
ASP.NET中的身份验证有那些
2012/07/13 面试题
软件工程师面试题
2012/06/25 面试题
迎八一活动主题
2014/01/31 职场文书
村干部群众路线整改措施思想汇报
2014/10/12 职场文书
2014年教研室工作总结
2014/12/06 职场文书
2015年党员承诺书
2015/01/21 职场文书
2016年推广普通话宣传周活动总结
2016/04/06 职场文书
用Python生成会跳舞的美女
2022/01/18 Python