render() {
return (
<div>
<label>输入内容</label>
<input value={this.state.inputValue}/>
<button onClick={this.handleBtnClick}>提交</button>
<Test content={this.state.inputValue}/>
</div>
)
}
实现react中render的几种方案(数据更新视图)
方案一:
- state 数据
- JSX 模板
- 数据 + 模板 结合,生成真实的DOM来显示
- state 发生改变
- 数据 + 模板 结合,生成真实的DOM,替换原始的DOM
缺陷:
每一次只要有一个state发生改变,都会生成一个新的完整的DOM片段来替换旧的,非常消耗内存(而实际上我们修改某一个state只需要依赖他的DOM元素被替换)
方案二:
- state 数据
- JSX 模板
- 数据 + 模板 结合,生成真实的DOM,来显示
- state 发生改变
- 数据 + 模板 结合, 生成真实的DOM,并不是直接替换原来的DOM
- 新的DOM 和 原始的DOM 作对比,找差异
- 找出依赖了变化的state的DOM元素
- 只用新的相关变化的元素,替换调老的DOM中的对应元素即可
缺陷:相比方案一虽然DOM替换的内容变少了,性能有所提升,但是又损耗了新的DOM与原始DOM对比的性能,所以性能提升并不明显。
方案三:
- state 数据
- JSX 模板
- 数据 + 模板 结合 生成虚拟DOM(虚拟DOM就是一个JS对象,用它来描述真实的DOM)(生成js对象和真实DOM相比,性能损耗极小)
// 第一个元素是标签名,第二个是属性,第三个是它的子元素
['div', {id: 'abc'}, ['span', {}, 'hello world']]
- 用上面虚拟DOM的结构生成真实的DOM,来显示
<div id="abc"><span>hello world</span></div>
- state 发生变化
- 数据 + 模板 生成新的虚拟DOM (极大地提升了性能)
['div', {id: 'abc'}, ['span', {}, 'bye bye']]
- 比较原始虚拟DOM和新的虚拟DOM的区别,找到区别是span中的内容变了(极大地提升了性能)
- 直接操作DOM,改变span中的内容
所以render的过程其实就是JSX -> createElement -> 虚拟DOM(JS对象)-> 真实DOM
虚拟DOM的好处
- 性能提升了(DOM比对变成了JS对象的比对)
- 使得跨段应用得以实现。React Native(因为如果没有虚拟DOM直接生成DOM在原生app里是不支持的,而js对象是支持的,可以转为原生的组件)
虚拟DOM中的Diff算法

-同层比对
如上图左右两边都是虚拟DOM,它会先比较第一级,如果相同再继续下一级,如果不同直接删除当前级别下的所有子节点的DOM,重新生成一遍当前节点下的所有DOM,然后用重新生成的DOM替换原始页面的DOM;
优点算法简单,比对的速度非常快;
缺点可能造成DOM节点上渲染的浪费;
- key值比对
列表循环的时候使用key值,为了提高虚拟DOM的比对性能,新旧虚拟DOM可以通过key值建立联系,所以key值要保持稳定,在项目中能不用index就不用index(如果使用index,比如有a,b,c三个那分别对应的索引就是0,1,2,可如果把a删了,b,c就分别对应0,1和之前的key值就对应不起来)

网友评论