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 相关文章推荐
IE DOM实现存在的部分问题及解决方法
Jul 25 Javascript
JavaScript实现快速排序(自已编写)
Dec 19 Javascript
SwfUpload在IE10上不出现上传按钮的解决方法
Jun 25 Javascript
js时间戳转为日期格式的方法
Dec 28 Javascript
jquery对dom节点的操作【推荐】
Apr 15 Javascript
JavaScript实现格式化字符串函数String.format
Dec 16 Javascript
js实现不提示直接关闭网页窗口
Mar 30 Javascript
浅谈vue-router 路由传参的方法
Dec 27 Javascript
JS立即执行函数功能与用法分析
Jan 15 Javascript
Node.js + express基本用法教程
Mar 14 Javascript
openlayers实现图标拖动获取坐标
Sep 25 Javascript
vue3.0中setup使用(两种用法)
Dec 02 Vue.js
基于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 daodb插入、更新与删除数据
2009/03/19 PHP
PHP实现加强版加密解密类实例
2015/07/29 PHP
PHP简单留言本功能实现代码
2017/06/09 PHP
suggestion开发小结以及对键盘事件的总结(针对中文输入法状态)
2011/12/20 Javascript
深入理解JavaScript系列(6) 强大的原型和原型链
2012/01/15 Javascript
javascript实现youku的视频代码自适应宽度
2015/05/25 Javascript
php输出全部gb2312编码内的汉字方法
2017/03/04 Javascript
关于TypeScript中import JSON的正确姿势详解
2017/07/25 Javascript
如何选择适合你的JavaScript框架
2017/11/20 Javascript
vue2.0实现前端星星评分功能组件实例代码
2018/02/12 Javascript
webpack组织模块打包Library的原理及实现
2018/03/10 Javascript
解决在Bootstrap模糊框中使用WebUploader的问题
2018/03/22 Javascript
个人小程序接入支付解决方案
2019/05/23 Javascript
RxJS的入门指引和初步应用
2019/06/15 Javascript
解决Vue router-link绑定事件不生效的问题
2020/07/22 Javascript
[05:06]2017亚洲邀请赛DAC回顾片
2017/04/19 DOTA
使用Python实现租车计费系统的两种方法
2018/09/29 Python
Windows下安装Scrapy
2018/10/17 Python
django实现web接口 python3模拟Post请求方式
2019/11/19 Python
Python导入模块包原理及相关注意事项
2020/03/25 Python
django haystack实现全文检索的示例代码
2020/06/24 Python
超酷炫 CSS3垂直手风琴菜单
2016/06/28 HTML / CSS
有750多个顶级品牌的瑞士时尚在线:ABOUT YOU
2017/01/04 全球购物
6PM官网:折扣鞋、服装及配饰
2018/08/03 全球购物
Made in Design意大利:现代家具、名家灯具和装饰
2020/10/27 全球购物
如何用Python输出一个Fibonacci数列
2016/08/28 面试题
大学教师年终总结的自我评价
2013/10/29 职场文书
中学生在校期间的自我评价分享
2013/11/13 职场文书
村抢险救灾方案
2014/05/09 职场文书
应聘教师求职信
2014/07/19 职场文书
工厂标语大全
2014/10/06 职场文书
三方股份合作协议书
2014/10/13 职场文书
党的作风建设心得体会
2014/10/22 职场文书
地陪导游欢迎词
2015/01/26 职场文书
村党组织公开承诺书
2015/04/30 职场文书
小学教师教学随笔
2015/08/14 职场文书