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 相关文章推荐
精解window.setTimeout()&amp;window.setInterval()使用方式与参数传递问题!
Nov 23 Javascript
jQuery ctrl+Enter shift+Enter实现代码
Feb 07 Javascript
javascript操作JSON的要领总结
Dec 09 Javascript
js Map List 遍历使用示例
Jul 10 Javascript
javascript实现base64 md5 sha1 密码加密
Sep 09 Javascript
Angular js 实现添加用户、修改密码、敏感字、下拉菜单的综合操作方法
Oct 24 Javascript
改变vue请求过来的数据中的某一项值的方法(详解)
Mar 08 Javascript
使用JSON格式提交数据到服务端的实例代码
Apr 01 Javascript
Angularjs Ng_repeat中实现复选框选中并显示不同的样式方法
Sep 12 Javascript
关于Vue项目跨平台运行问题的解决方法
Sep 18 Javascript
Vue 组件的挂载与父子组件的传值实例
Sep 02 Javascript
JavaScript实现缓动动画
Nov 25 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 批量更新网页内容实现代码
2010/01/05 PHP
php替换超长文本中的特殊字符的函数代码
2012/05/22 PHP
Thinkphp模板中使用自定义函数的方法
2012/09/23 PHP
Destoon实现多表查询示例
2014/08/21 PHP
PHP中abstract(抽象)、final(最终)和static(静态)原理与用法详解
2020/06/05 PHP
通过JAVAScript实现页面自适应
2007/01/19 Javascript
jQuery UI Datepicker length为空或不是对象错误的解决方法
2010/12/19 Javascript
jquery如何改变html标签的样式(两种实现方法)
2013/01/16 Javascript
jQuery实现的原图对比窗帘效果
2014/06/15 Javascript
详解JavaScript正则表达式之RegExp对象
2015/12/13 Javascript
学习使用grunt来打包JavaScript和CSS程序的教程
2016/01/04 Javascript
使用Jasmine和Karma对AngularJS页面程序进行测试
2016/03/05 Javascript
基于jQuery实现中英文切换导航条效果
2016/09/18 Javascript
聊一聊JS中的prototype
2016/09/29 Javascript
JavaScript 身份证号有效验证详解及实例代码
2016/10/20 Javascript
JS前端加密算法示例
2016/12/22 Javascript
jquery.form.js异步提交表单详解
2017/04/25 jQuery
vue.js中mint-ui框架的使用方法
2017/05/12 Javascript
webpack4的迁移的使用方法
2018/05/25 Javascript
Vue不能观察到数组length的变化
2018/06/08 Javascript
vue prop传值类型检验方式
2020/07/30 Javascript
详解vue中使用transition和animation的实例代码
2020/12/12 Vue.js
vue使用require.context实现动态注册路由
2020/12/25 Vue.js
Python自动化开发学习之三级菜单制作
2017/07/14 Python
python3 pillow生成简单验证码图片的示例
2017/09/19 Python
Python模拟自动存取款机的查询、存取款、修改密码等操作
2018/09/02 Python
对pandas读取中文unicode的csv和添加行标题的方法详解
2018/12/12 Python
python爬虫爬取网页数据并解析数据
2020/09/18 Python
详解使用CSS3的@media来编写响应式的页面
2017/11/01 HTML / CSS
HMV日本官网:全球知名的音乐、DVD和电脑游戏零售巨头
2016/08/13 全球购物
优质美利奴羊毛袜,不只是徒步旅行:Darn Tough Vermont
2018/11/05 全球购物
eBay爱尔兰站:eBay.ie
2019/08/09 全球购物
运动会表扬稿大全
2014/01/16 职场文书
《卖木雕的少年》教学反思
2014/04/11 职场文书
生物科学专业自荐书
2014/06/20 职场文书
Windows Server 2012 R2 磁盘分区教程
2022/04/29 Servers