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代码
Mar 06 Javascript
javascript 窗口加载蒙板 内嵌网页内容
Nov 19 Javascript
各情景下元素宽高的获取实现代码
Sep 13 Javascript
JavaScript instanceof 的使用方法示例介绍
Oct 23 Javascript
table insertRow、deleteRow定义和用法总结
May 14 Javascript
JS实现的简洁纵向滑动菜单(滑动门)效果
Oct 19 Javascript
js实现iframe框架取值的方法(兼容IE,firefox,chrome等)
Nov 26 Javascript
H5实现仿flash效果的实现代码
Sep 29 Javascript
vue项目如何刷新当前页面的方法
May 18 Javascript
Angular6使用forRoot() 注册单一实例服务问题
Aug 27 Javascript
在vue中把含有html标签转为html渲染页面的实例
Oct 28 Javascript
Echarts实现多条折线可拖拽效果
Dec 19 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得到某段时间区间的时间戳 php定时任务
2012/04/12 PHP
codeigniter中测试通过的分页类示例
2014/04/17 PHP
php截取字符串函数substr,iconv_substr,mb_substr示例以及优劣分析
2014/06/10 PHP
PHP实现多关键字加亮功能
2016/10/21 PHP
浅谈php中的循环while、do...while、for、foreach四种循环
2016/11/05 PHP
php大小写转换函数(strtolower、strtoupper)用法介绍
2017/11/17 PHP
PHP实现正则匹配所有括号中的内容
2018/06/22 PHP
基于PHP实现邮箱验证激活过程详解
2020/10/28 PHP
js中的值类型和引用类型小结 文字说明与实例
2010/12/12 Javascript
js 调用本地exe的例子(支持IE内核的浏览器)
2012/12/26 Javascript
JavaScript的History API使搜索引擎抓取AJAX内容
2015/12/07 Javascript
js控制TR的显示隐藏
2016/03/04 Javascript
Angularjs material 实现搜索框功能
2016/03/08 Javascript
温习Javascript基础语法之词法结构
2016/05/31 Javascript
Vue编写多地区选择组件
2017/08/21 Javascript
Vue打包后出现一些map文件的解决方法
2018/02/13 Javascript
微信小程序日期选择器实例代码
2018/07/18 Javascript
微信小程序实现多选功能
2018/11/04 Javascript
解决vue2中使用elementUi打包报错的问题
2020/09/22 Javascript
Ant Design的Table组件去除
2020/10/24 Javascript
python 获取et和excel的版本号
2009/04/09 Python
python中引用与复制用法实例分析
2015/06/04 Python
用Python解决计数原理问题的方法
2016/08/04 Python
python学生信息管理系统(完整版)
2020/04/05 Python
Python3实现对列表按元组指定列进行排序的方法分析
2018/12/22 Python
python 使用多线程创建一个Buffer缓存器的实现思路
2020/07/02 Python
基于Python实现全自动下载抖音视频
2020/11/06 Python
世界上最大的罕见唱片、CD和音乐纪念品网上商店:991.com
2018/05/03 全球购物
编写一子程序,将一链表倒序,即使链表表尾变表头,表头变表尾
2016/02/10 面试题
毕业生就业自荐书
2013/12/15 职场文书
自荐信格式简述
2014/01/25 职场文书
2014村务公开实施方案
2014/02/25 职场文书
《火烧云》教学反思
2014/04/12 职场文书
初中中等生评语
2014/12/29 职场文书
运动会加油稿30字
2015/07/21 职场文书
pytorch 如何把图像数据集进行划分成train,test和val
2021/05/31 Python