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 日期转换成中文格式的函数
Jul 07 Javascript
防止页面被iframe(兼容IE,Firefox火狐)
Jul 04 Javascript
JavaScript 错误处理与调试经验总结
Aug 10 Javascript
文本框input聚焦失焦样式实现代码
Oct 12 Javascript
Javascript快速排序算法详解
Dec 03 Javascript
javascript实现按回车键切换焦点
Feb 09 Javascript
javascript获取当前的时间戳的方法汇总
Jul 26 Javascript
纯js模拟div层弹性运动的方法
Jul 27 Javascript
js实现简单的获取验证码按钮效果
Mar 03 Javascript
jQuery插件HighCharts绘制的2D堆柱状图效果示例【附demo源码下载】
Mar 14 Javascript
js中null与空字符串&quot;&quot;的区别讲解
Jan 17 Javascript
详解JavaScript的变量
Apr 04 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 命名空间实例说明
2011/01/27 PHP
php循环创建目录示例分享(php创建多级目录)
2014/03/04 PHP
php绘制一个矩形的方法
2015/01/24 PHP
php单例模式示例分享
2015/02/12 PHP
PHP实现的Redis多库选择功能单例类
2017/07/27 PHP
PHP静态延迟绑定和普通静态效率的对比
2017/10/20 PHP
PHP重置数组为连续数字索引的几种方式总结
2018/03/12 PHP
Mac系统下安装PHP Xdebug
2018/03/30 PHP
传递参数的标准方法(jQuery.ajax)
2008/11/19 Javascript
js trim函数 去空格函数与正则集锦
2009/11/20 Javascript
利用json获取字符出现次数的代码
2012/03/22 Javascript
js实现两个值相加alert出来精确到指定位
2013/09/25 Javascript
json属性名为什么要双引号(个人猜测)
2014/07/31 Javascript
javascript操作Cookie(设置、读取、删除)方法详解
2015/03/18 Javascript
JS实现兼容性较好的随屏滚动效果
2015/11/09 Javascript
Bootstrap3制作图片轮播效果
2016/05/12 Javascript
用JS实现图片轮播效果代码(一)
2016/06/26 Javascript
Node.js 使用AngularJS的方法示例
2018/05/11 Javascript
解决vue 退出动画无效的问题
2020/08/09 Javascript
vue集成一个支持图片缩放拖拽的富文本编辑器
2021/01/29 Vue.js
Python3实现的回文数判断及罗马数字转整数算法示例
2019/03/27 Python
在pandas中遍历DataFrame行的实现方法
2019/10/23 Python
tensorflow/core/platform/cpu_feature_guard.cc:140] Your CPU supports instructions that this T
2020/06/22 Python
Python实现快速大文件比较代码解析
2020/09/04 Python
anaconda升级sklearn版本的实现方法
2021/02/22 Python
魔声耳机官方网站:Monster是世界第一品牌的高性能耳机
2016/10/26 全球购物
独特的礼品和创新的科技产品:The Grommet
2018/02/24 全球购物
来自南加州灵感的工作和娱乐服装:TravisMathew
2019/05/01 全球购物
一年级班主任寄语
2014/01/19 职场文书
买房协议书范本
2014/10/23 职场文书
烟台的海导游词
2015/02/02 职场文书
支行行长岗位职责
2015/02/15 职场文书
毕业论文致谢部分怎么写
2015/05/14 职场文书
2016年企业安全生产月活动总结
2016/04/06 职场文书
带你学习MySQL执行计划
2021/05/31 MySQL
Django数据库(SQlite)基本入门使用教程
2022/07/07 Python