HTML5技术

【react框架】利用shouldComponentUpdate钩子函数优化react性能以及引入immutable库的(4)

字号+ 作者:H5之家 来源:H5之家 2017-04-16 09:02 我要评论( )

let a =2 ,b;b = a; // 将a的值赋给b a = 1; // 改变a的值 console.log('a =' + a); // 输出 a = 1 console.log('b =' + b); // 输出 b = 2,表明赋值后b,a毫无关联 对于引用类型变量obj1和obj2,obj1 = obj2后,访

let a =2,b; b = a;//将a的值赋给b a = 1;//改变a的值 console.log('a =' + a);//输出 a = 1 console.log('b =' + b);//输出 b = 2,表明赋值后b,a毫无关联

对于引用类型变量obj1和obj2,obj1 = obj2后,访问obj1和obj2相当于访问同一个变量,两者形成了一种“耦合”的关系

let obj1 ={name:'李达康'},obj2; obj2 = obj1;//将obj1的地址赋给obj2 obj1.name = '祁同伟';//改变obj1的name属性值 console.log('obj1.name =' + obj1.name);//输出 obj1.name = '祁同伟' console.log('obj2.name =' + obj2.name);//输出 obj2.name = '祁同伟',表明赋值后obj1/obj2形成耦合关系,两者互相影响

 

为什么基本类型和引用类型在变量赋值上面存在这么大的不同呢?因为基本类型变量占用的内存很小,而引用类型变量占用的内存比较大,几个引用类型变量通过指针共享同一个变量可以节约内存

 

所以,在这个例子中,我们上面和下面所做的一切,都是在消除对象赋值表达式所带来的这一负面影响

 

那我们能不能通过一些方式,使得preNumberArray = this.state.numberArray的时候,两变量指向的就是不同的两个对象呢?于是这里就引入了一个强大的第三方库 ——immutable.js,先举个例子示范一下:

(首先要通过npm install immutable 安装immutable的依赖包哦)

const { fromJS } = require('immutable') let obj1 = fromJS({name:'李达康'}),obj2; obj2 = obj1;//obj2取得与obj1相同的值,但两个引用指向不同的对象 obj2 = obj2.set('name','祁同伟');//设置obj2的name属性值为祁同伟 console.log('obj1.name =' + obj1.get('name'));//obj1.name =李达康 console.log('obj2.name =' + obj2.get('name'));//obj2.name =祁同伟

【注意】

1这个时候obj1=obj2并不会使两者指向同一个堆内存中的对象了!所以这成功绕过了我们前面的所提到的对象赋值表达式所带来的坑。所以我们可以随心所欲地像使用普通基本类型变量复制 (a=b)那样对对象等引用类型赋值(obj1 = obj2)而不用拷贝新对象

2对于immutable对象,你不能再用obj.属性名那样取值了,你必须使用immuutable提供的API

1优点:深拷贝/浅拷贝本身是很耗内存,而immutable本身有一套机制使内存消耗降到最低

2缺点:你多了一整套的API去学习,并且immutable提供的set,map等对象容易与ES6新增的set,map对象弄混

让我们一试为快:

import React from 'react' const { fromJS } = require('immutable') class Son extends React.Component{ shouldComponentUpdate(nextProps,nextState){ (nextProps.numberObject.get('number') == this.props.numberObject.get('number')){ return false } return true } render(){ const {index,numberObject,handleClick} = this.props console.log(numberObject.get('number')); <h1 onClick ={() => handleClick(index)}>{numberObject.get('number')}</h1> } } class Father extends React.Component{ constructor(props) { super(props); this.state = { numberArray:fromJS([{number:0 }, {number:1 }, {number:2 } ]) } } //点击后使numberArray中数组下标为index的数字值加一,重渲染对应的Son组件 handleClick = (index) => { let preNumberArray = this.state.numberArray //使新的number Object对象的number属性加一,旧的number Object对象属性不变 let newNumber = preNumberArray.get(index).get('number') + 1; preNumberArray = preNumberArray.set(index,fromJS({number: newNumber})); this.setState({numberArray:preNumberArray}) } render(){ return(<div style ={{margin:30}}>{ this.state.numberArray.map( (numberObject,key) => { return <Son key = {key} index = {key} numberObject ={numberObject} handleClick ={this.handleClick}/> } ) } </div>) } } export default Father

成功,demo效果同上

 

这篇文章实在太过冗长,不过既然您已经看到这里了,那么我就介绍解决上述问题的一种简单粗暴的方法——

4继承react的PureComponent组件

如果你只是单纯地想要避免state和props不变下的冗余的重渲染,那么react的pureComponent可以非常方便地实现这一点:

import React, { PureComponent } YouComponent extends PureComponent { render() { // ... } }

当然了,它并不是万能的,由于选择性得忽略了shouldComponentUpdate()这一钩子函数,它并不能像shouldComponentUpdate()“私人定制”那般随心所欲

具体代码就不放了

【完】

 

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

相关文章
  • net.sz.framework 框架 登录服务器架构 单服2 万 TPS(QPS) - 失足程序员

    net.sz.framework 框架 登录服务器架构 单服2 万 TPS(QPS) - 失足

    2017-04-13 11:05

  • 前端开发框架简介:angular和react - 腾讯云技术社区

    前端开发框架简介:angular和react - 腾讯云技术社区

    2017-04-11 18:02

  • WebApp框架 - stumpx

    WebApp框架 - stumpx

    2017-04-06 15:01

  • net.sz.framework 框架 轻松搭建服务---让你更专注逻辑功能---初探 - 失足程序员

    net.sz.framework 框架 轻松搭建服务---让你更专注逻辑功能---初探 -

    2017-04-02 10:11

网友点评
a