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 的全选(全非选)即取得被选中的值使用介绍
Nov 12 Javascript
javascript操作css属性
Dec 30 Javascript
一个字符串反转函数可实现字符串倒序
Sep 15 Javascript
jQuery unbind()方法实例详解
Jan 19 Javascript
Vuejs第十篇之vuejs父子组件通信
Sep 06 Javascript
微信小程序 Tab页切换更新数据
Jan 05 Javascript
canvas实现环形进度条效果
Mar 23 Javascript
Nuxt.js实现校验访问浏览器类型的中间件
Aug 24 Javascript
Node.js实现一个HTTP服务器的方法示例
May 13 Javascript
webpack+express实现文件精确缓存的示例代码
Jun 11 Javascript
在antd Form表单中select设置初始值操作
Nov 02 Javascript
vue element-ul实现展开和收起功能的实例代码
Nov 25 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优化需要注意的地方
2014/11/27 PHP
PHP使用Curl实现模拟登录及抓取数据功能示例
2018/04/27 PHP
使用js检测浏览器的实现代码
2013/05/14 Javascript
JQuery for与each性能比较分析
2013/05/14 Javascript
利用NodeJS和PhantomJS抓取网站页面信息以及网站截图
2013/11/18 NodeJs
javascript如何创建表格(javascript绘制表格的二种方法)
2013/12/10 Javascript
JavaScript操作Cookie详解
2015/02/28 Javascript
JS验证逗号隔开可以是中文字母数字
2016/04/22 Javascript
响应式表格之固定表头的简单实现
2016/08/26 Javascript
JavaScript提高加载和执行效率的方法
2017/02/03 Javascript
基于angular实现模拟微信小程序swiper组件
2017/06/11 Javascript
Vue学习笔记进阶篇之vue-cli安装及介绍
2017/07/18 Javascript
Nodejs连接mysql并实现增、删、改、查操作的方法详解
2018/01/04 NodeJs
Vue 使用 Mint UI 实现左滑删除效果CellSwipe
2018/04/27 Javascript
对类Vue的MVVM前端库的实现代码
2018/09/07 Javascript
vue-cli中使用高德地图的方法示例
2019/03/28 Javascript
使用jQuery mobile NuGet让你的网站在移动设备上同样精彩
2019/06/18 jQuery
vue 百度地图(vue-baidu-map)绘制方向箭头折线实例代码详解
2020/04/28 Javascript
python实现PID算法及测试的例子
2019/08/08 Python
python装饰器原理与用法深入详解
2019/12/19 Python
Python任务调度模块APScheduler使用
2020/04/15 Python
python破解同事的压缩包密码
2020/10/14 Python
Python获取android设备cpu和内存占用情况
2020/11/15 Python
websocket+sockjs+stompjs详解及实例代码
2018/11/30 HTML / CSS
YOINS官网:时尚女装网上购物
2017/03/17 全球购物
Jacadi Paris美国官方网站:法国童装品牌
2017/10/15 全球购物
GOOD AMERICAN官网:为曲线性感而设计
2017/12/28 全球购物
捷克体育用品购物网站:D-sport
2017/12/28 全球购物
英国鲜花速递:Serenata Flowers
2018/04/03 全球购物
Nike澳大利亚官网:Nike.com (AU)
2019/06/03 全球购物
建筑工程自我鉴定
2013/10/18 职场文书
初中数学教学反思
2014/01/16 职场文书
新学期班主任寄语
2014/01/18 职场文书
学生生病请假条范文
2014/02/16 职场文书
MYSQL常用函数介绍
2022/05/05 MySQL
springcloud整合seata
2022/05/20 Java/Android