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 相关文章推荐
jQuery 常见开发使用技巧总结
Dec 26 Javascript
IE中的File域无法清空使用jQuery重设File域
Apr 24 Javascript
JavaScript中停止执行setInterval和setTimeout事件的方法
May 14 Javascript
JavaScript function函数种类详解
Feb 22 Javascript
jquery attr()设置和获取属性值实例教程
Sep 25 Javascript
简单实现js悬浮导航效果
Feb 05 Javascript
用javascript获取任意颜色的更亮或更暗颜色值示例代码
Jul 21 Javascript
js弹性势能动画之抛物线运动实例详解
Jul 27 Javascript
vue实现在v-html的html字符串中绑定事件
Oct 28 Javascript
js消除图片小游戏代码
Dec 11 Javascript
JavaScript实现随机点名器
Mar 25 Javascript
JS highcharts实现动态曲线代码示例
Oct 16 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
DOTA2游戏同人动画《龙之血》导演接受采访
2021/03/05 欧美动漫
用Flash图形化数据(一)
2006/10/09 PHP
屏蔽机器人从你的网站搜取email地址的php代码
2012/11/14 PHP
基于python发送邮件的乱码问题的解决办法
2013/04/25 PHP
mac os快速切换多个PHP版本的方法
2017/03/07 PHP
分析php://output和php://stdout的区别
2018/05/06 PHP
用js实现的抽象CSS圆角效果!!
2007/05/03 Javascript
js不完美解决click和dblclick事件冲突问题
2012/07/16 Javascript
js 动态加载事件的几种方法总结
2013/12/25 Javascript
jquery分页插件jquery.pagination.js使用方法解析
2016/04/01 Javascript
jQuery插件Echarts实现的双轴图效果示例【附demo源码下载】
2017/03/04 Javascript
解决angularjs中同步执行http请求的方法
2018/08/13 Javascript
webpack file-loader和url-loader的区别
2019/01/15 Javascript
vue项目中将element-ui table表格写成组件的实现代码
2019/06/12 Javascript
微信小程序中weui用法解析
2019/10/21 Javascript
JavaScript实现电灯开关小案例
2020/03/30 Javascript
[06:21]完美世界亚洲区首席发行官竺琦TI3采访
2013/08/26 DOTA
Python命令行参数解析模块getopt使用实例
2015/04/13 Python
Python3实现将文件树中所有文件和子目录归档到tar压缩文件的方法
2015/05/22 Python
微信跳一跳python自动代码解读1.0
2018/01/12 Python
Python读取word文本操作详解
2018/01/22 Python
Tensorflow卷积神经网络实例进阶
2018/05/24 Python
Python嵌套列表转一维的方法(压平嵌套列表)
2018/07/03 Python
python3 http提交json参数并获取返回值的方法
2018/12/19 Python
基于Django signals 信号作用及用法详解
2020/03/28 Python
在python中修改.properties文件的操作
2020/04/08 Python
Ray-Ban雷朋瑞典官方网站:全球领先的太阳眼镜品牌
2019/08/22 全球购物
知识竞赛活动方案
2014/02/18 职场文书
学生会主席竞聘书
2014/03/31 职场文书
说明书范文
2014/05/07 职场文书
销售员未完成销售业绩的检讨书
2014/10/12 职场文书
公民授权委托书
2014/10/15 职场文书
2014年旅游局法制宣传日活动总结
2014/11/01 职场文书
2015年爱牙日活动总结
2015/02/05 职场文书
劳动者解除劳动合同通知书
2015/04/16 职场文书
2015年社区党建工作汇报材料
2015/06/25 职场文书