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代码
Jan 01 Javascript
js中的值类型和引用类型小结 文字说明与实例
Dec 12 Javascript
JavaScript数值转换的三种方式总结
Jul 31 Javascript
jQuery实现多按钮单击变色
Nov 27 Javascript
纯Javascript实现ping功能的方法
Mar 20 Javascript
Boostrap基础教程之JavaScript插件篇
Sep 08 Javascript
基于javascript实现按圆形排列DIV元素(二)
Dec 02 Javascript
详解vue-validator(vue验证器)
Jan 16 Javascript
vue+mockjs模拟数据实现前后端分离开发的实例代码
Aug 08 Javascript
使用async await 封装 axios的方法
Jul 09 Javascript
微信小程序实现多选功能
Nov 04 Javascript
一文了解JavaScript用Element Traversal新属性遍历子元素
Nov 27 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
PHP+javascript模拟Matrix画面
2006/10/09 PHP
php不用正则验证真假身份证
2013/11/06 PHP
CI框架简单邮件发送类实例
2016/05/18 PHP
遍历echsop的region表形成缓存的程序实例代码
2016/11/01 PHP
PHP下载文件函数与用法示例
2019/09/27 PHP
jQuery 源码分析笔记(7) Queue
2011/06/19 Javascript
Json2Template.js 基于jquery的插件 绑定JavaScript对象到Html模板中
2011/10/29 Javascript
jQuery中ajax的使用与缓存问题的解决方法
2013/12/19 Javascript
通过url查找a元素应用案例
2014/04/29 Javascript
javascript中call和apply的用法示例分析
2015/04/02 Javascript
canvas实现图像截取功能
2017/02/06 Javascript
Bootstrap下拉菜单更改为悬停(hover)触发的方法
2017/05/24 Javascript
vue cli使用绝对路径引用图片问题的解决
2017/12/06 Javascript
Vue.js特性Scoped Slots的浅析
2019/02/20 Javascript
vue中使用props传值的方法
2019/05/08 Javascript
vue路由传参页面刷新参数丢失问题解决方案
2019/10/08 Javascript
JavaScript实现抖音罗盘时钟
2019/10/11 Javascript
Element MessageBox弹框的具体使用
2020/07/27 Javascript
使用wxPython获取系统剪贴板中的数据的教程
2015/05/06 Python
Python实现简单拆分PDF文件的方法
2015/07/30 Python
python 爬取微信文章
2016/01/30 Python
python 遍历字符串(含汉字)实例详解
2017/04/04 Python
今天 平安夜 Python 送你一顶圣诞帽 @微信官方
2017/12/25 Python
python 二维数组90度旋转的方法
2019/01/28 Python
由Python编写的MySQL管理工具代码实例
2019/04/09 Python
python3+PyQt5 自定义窗口部件--使用窗口部件样式表的方法
2019/06/26 Python
python对 MySQL 数据库进行增删改查的脚本
2020/10/22 Python
使用OpenCV实现人脸图像卡通化的示例代码
2021/01/15 Python
Bench加拿大官方网站:英国城市服装品牌
2017/11/03 全球购物
Boom手表官网:瑞典手表品牌,设计你的手表
2019/03/11 全球购物
三万活动总结
2014/04/28 职场文书
主题团日活动总结
2014/06/25 职场文书
2014年卫生工作总结
2014/11/27 职场文书
违纪检讨书
2015/01/27 职场文书
《用字母表示数》教学反思
2016/02/17 职场文书
WordPress多语言翻译插件 - WPML使用教程
2021/04/01 PHP