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 相关文章推荐
JavaScript实现鼠标滑过图片变换效果的方法
Apr 16 Javascript
JS基于面向对象实现的放烟花效果
May 07 Javascript
JavaScript原生xmlHttp与jquery的ajax方法json数据格式实例
Dec 04 Javascript
学习JavaScript设计模式之模板方法模式
Jan 20 Javascript
Javascript类型转换的规则实例解析
Feb 23 Javascript
javaScript数组迭代方法详解
Apr 14 Javascript
jQuery过滤选择器经典应用
Aug 18 Javascript
Angular.js中用ng-repeat-start实现自定义显示
Oct 18 Javascript
javascript设计模式之单体模式学习笔记
Feb 15 Javascript
bootstrap实现的自适应页面简单应用示例
Mar 09 Javascript
解决IE11 vue +webpack 项目中数据更新后页面没有刷新的问题
Sep 25 Javascript
Vue插值、表达式、分隔符、指令知识小结
Oct 12 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
一个分页的论坛
2006/10/09 PHP
PHP 二维array转换json的实例讲解
2018/08/21 PHP
php设计模式之迭代器模式实例分析【星际争霸游戏案例】
2020/04/07 PHP
比较不错的JS/JQuery显示或隐藏文本的方法
2014/02/13 Javascript
javascript中的undefined和not defined区别示例介绍
2014/02/26 Javascript
学习JavaScript设计模式之享元模式
2016/01/18 Javascript
原生js实现图片层叠轮播切换效果
2016/02/02 Javascript
关于数据与后端进行交流匹配(点亮星星)
2016/08/03 Javascript
JS 滚动事件window.onscroll与position:fixed写兼容IE6的回到顶部组件
2016/10/10 Javascript
通过扫描二维码打开app的实现代码
2016/11/10 Javascript
微信小程序tabbar不显示解决办法
2017/06/08 Javascript
详解angularJS自定义指令间的相互交互
2017/07/05 Javascript
layer弹出子iframe层父子页面传值的实现方法
2018/11/22 Javascript
详解ES7 Decorator 入门解析
2019/02/18 Javascript
基于leaflet.js实现修改地图主题样式的流程分析
2020/05/15 Javascript
Python中函数的参数传递与可变长参数介绍
2015/06/30 Python
浅谈Python 中整型对象的存储问题
2016/05/16 Python
利用python编写一个图片主色转换的脚本
2017/12/07 Python
Python3中详解fabfile的编写
2018/06/24 Python
Python不同目录间进行模块调用的实现方法
2019/01/29 Python
详解Python爬取并下载《电影天堂》3千多部电影
2019/04/26 Python
django中使用POST方法获取POST数据
2019/08/20 Python
基于numpy中的expand_dims函数用法
2019/12/18 Python
python的链表基础知识点
2020/09/13 Python
利用CSS3的定位页面元素
2009/08/29 HTML / CSS
html5 canvas合成海报所遇问题及解决方案总结
2017/08/03 HTML / CSS
介绍一下木马病毒的种类
2015/07/26 面试题
nohup的用法
2012/11/26 面试题
市场部专员岗位职责
2013/11/30 职场文书
大学生志愿者感言
2014/01/15 职场文书
反邪教宣传工作方案
2014/05/07 职场文书
学习党的群众路线剖析材料
2014/10/09 职场文书
暖春观后感
2015/06/08 职场文书
人民调解协议书
2016/03/21 职场文书
您对思维方式了解多少?
2019/12/09 职场文书
Redis sentinel哨兵集群的实现步骤
2022/07/15 Redis