天天看点

react学习笔记1(diff算法和Component相关)1. diff算法2. Component、PureComponent和Immutable3. 参考链接

目录

  • 1. diff算法
        • 1.1 diff 算法的作用
        • 1.2 reconcilition(调和)
        • 1.3 diff算法优化
        • 1.4 tree diff
        • 1.5 component diff
        • 1.6 element diff
  • 2. Component、PureComponent和Immutable
        • 2.1 shouldComponentUpdate函数
        • 2.2 React.PureComponent
        • 2.3 Component、PureComponent和Immutable
  • 3. 参考链接

1. diff算法

1.1 diff 算法的作用

去掉多余的 DOM 操作,提升web app性能

1.2 reconcilition(调和)

  • 定义:将Virtual DOM树转换成actual DOM树的最少操作的过程。diff 算法是调和的具体实现
  • 过程: 渲染时调用 render 方法(返回 Virtual Dom 树),比较渲染前后 虚拟dom(Virtual Dom) 的差别,Rendering 时,只更新差别部分(精准update),以减少多余 Dom 操作

1.3 diff算法优化

  • 传统 diff 算法 问题: 计算耗时,时间复杂度:O(n^3)
  • react diff :时间复杂度 O(n)
  • react diff 的三大策略
    • 进行同层比较(tree diff)
    • 不同类的 React 组件,被当做不同的 Dom 结构而替换(component diff)
    • key prop:组件 身份标识,判断是否是同一组件 (element diff)

1.4 tree diff

  • 跨层级Dom操作:创建节点,删除节点
  • 官方建议:不要进行跨层级操作(使用显示/隐藏,代替删除/新增操作)

1.5 component diff

  • 组件变化时,如果 virtual dom 没变,可通过 shouldComponentUpdate 方法控制是否需要 diff 运算
  • 组件类不同(结构相似),则判断为 dirty component(脏组件),整个替换

1.6 element diff

  • 同层节点 diff 操作:删除、插入、移动
  • 移动:尽量减少将类似最后一个元素移动到列表首部的操作(时间复杂度:O(n))
  • 图:
f(['A','B','C','D'],['D','A','B','C'])		//3
f(['A','B','C','D'],['B','A','D','C'])		//2
f(['A','B','C','D'],['B','E','A','C'])		//3
//返回移动、插入、删除操作的总次数
function f(old, newS){
	var operates = 0	
	var lastIndex = 0
	//新集合遍历,判断是否需要移动、插入
	for(let [i,v] of newS.entries()){
		let index = old.indexOf(v)
		if(index != -1){
			if(lastIndex > index){
				//移动操作
				operates++
			}
			lastIndex = Math.max(index, lastIndex)
		}else{
			lastIndex = i
			operates++
		}
	}
	//旧集合遍历,计算删除的节点
	for(let v of old){
		if(!newS.includes(v)){
			//删除的相关操作
			operates++
		}
	}
	return operates
}

           

2. Component、PureComponent和Immutable

2.1 shouldComponentUpdate函数

  • 监听 props 和 state 的变化(适用于状态少的组件)
class My extends  React.Component{
	shouldComponentUpdate(nextProps, nextState){
		if(this.props.color != nextProps.props.color){
			return true
		}else if(this.state.count != nextProps.count){
			return true
		}else{
			return false
		}
	}
}
           

2.2 React.PureComponent

  • React.PureComponent中, shouldComponentUpate对prop和state进行浅对比,没变化则不渲染
  • state 和 props 的数据为引用类型时,只会比较数据地址
  • 问题:修改对象值,地址不变
  • 解决方案:生成新对象,以改变对象内存地址
class My extends React.PureComponent {
	state = {
		obj: {}
	}
	change(){
		let {obj} = this.state
		this.setState({
			obj: {...obj}
		})
	}
}
           

2.3 Component、PureComponent和Immutable

  • React.Component 中,shouldComponentUpate始终返回true,只要有变化,就渲染全部(子组件)
  • PureComponent省去了virtual dom的对比过程, 可提升性能
  • forceUpate方法: 跳过该组件的 shouldComponentUpdate,调用 render
  • 使用 Immutable 可复制数据到新的内存,比直接拷贝 效率高

3. 参考链接

  1. https://blog.csdn.net/weixin_43606158/article/details/89425451
  2. https://www.jianshu.com/p/3ba0822018cf
  3. https://blog.csdn.net/liwusen/article/details/53908266
  4. https://blog.csdn.net/sinat_36422236/article/details/81117961
  5. https://www.jianshu.com/p/2fbf85744117

继续阅读