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 prototype 格式化数字 By shawl.qiu
Apr 02 Javascript
基于jquery的拖动布局插件
Nov 25 Javascript
Eval and new funciton not the same thing
Dec 27 Javascript
javascript实现颜色渐变的方法
Oct 30 Javascript
javascript中AJAX用法实例分析
Jan 30 Javascript
JS+CSS实现可拖拽的漂亮圆角特效弹出层完整实例
Feb 13 Javascript
jQuery实现下滑菜单导航效果代码
Aug 25 Javascript
基于jQuery实现点击最后一行实现行自增效果的表格
Jan 12 Javascript
原生javascript实现的一个简单动画效果
Mar 30 Javascript
深入理解JS正则表达式---分组
Jul 18 Javascript
微信小程序按钮点击跳转页面详解
May 06 Javascript
js实现简单的点名器随机色实例代码
Sep 20 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防止跨域提交表单
2013/11/01 PHP
js+php实现静态页面实时调用用户登陆状态的方法
2015/01/04 PHP
Windows平台实现PHP连接SQL Server2008的方法
2017/07/26 PHP
PHP7导出Excel报ERR_EMPTY_RESPONSE解决方法
2019/04/16 PHP
js中关于String对象的replace使用详解
2011/05/24 Javascript
js仿百度有啊通栏展示效果实现代码
2013/05/28 Javascript
JavaScript定时器详解及实例
2013/08/01 Javascript
判断及设置浏览器全屏模式
2014/04/20 Javascript
JavaScript中的类(Class)详细介绍
2014/12/30 Javascript
js实现的Easy Tabs选项卡用法实例
2015/09/06 Javascript
谈一谈javascript中继承的多种方式
2016/02/19 Javascript
jQuery获取字符串中出现最多的数
2016/02/22 Javascript
关于微信上网页图片点击全屏放大效果
2016/12/19 Javascript
BootStrapTable 单选及取值的实现方法
2017/01/10 Javascript
vue.js实现请求数据的方法示例
2017/02/07 Javascript
Vue.js常用指令之循环使用v-for指令教程
2017/06/27 Javascript
vue中的非父子间的通讯问题简单的实例代码
2017/07/19 Javascript
JavaScript 中的 this 工作原理
2018/06/20 Javascript
vue如何在项目中调用腾讯云的滑动验证码
2020/07/15 Javascript
Python学习之asyncore模块用法实例教程
2014/09/29 Python
python连接oracle数据库实例
2014/10/17 Python
不可错过的十本Python好书
2017/07/06 Python
Python基于正则表达式实现文件内容替换的方法
2017/08/30 Python
python pcm音频添加头转成Wav格式文件的方法
2019/01/09 Python
使用Keras预训练模型ResNet50进行图像分类方式
2020/05/23 Python
css3强大的动画效果animate使用说明及浏览器兼容介绍
2013/01/09 HTML / CSS
美国知名女性服饰品牌:New York & Company
2017/03/23 全球购物
澳大利亚领先的女性运动服品牌:Lorna Jane
2020/06/19 全球购物
优秀班主任经验交流材料
2014/06/02 职场文书
“九一八事变纪念日”国旗下讲话稿
2014/09/14 职场文书
2014旅游局党组书记党建工作汇报材料
2014/11/02 职场文书
房屋认购协议书
2015/01/29 职场文书
优秀大学生自荐信
2015/03/26 职场文书
预备党员考察表党小组意见
2015/06/01 职场文书
优秀范文:《但愿人长久》教学反思3篇
2019/10/24 职场文书
Docker与K8s关系介绍不会Docker也可以使用K8s
2022/06/25 Servers