染方式:
第一种方式: 整体替换DOM
1、 state数据
2、 JSX 模板
3、 数据 + 模板 生成真实的DOM 来显示
4、 state 发生变化
5、 数据 + 模板 生成真实的DOM, 替换原始的DOM
缺陷:
第一次生成了一个完整的DOM片段
第二次生成一个完整的DOM片段
第二次的DOM替换第一次DOM, 非常耗性能
第二种方式: 替换DOM中的差异部分
1、 state数据
2、 JSX 模板
3、 数据 + 模板 生成真实的DOM 来显示
4、 state 发生变化
5、 数据 + 模板 生成真实的DOM, 并不直接替换原始的DOM
6、 新的DOM和原始的DOM 做对比, 找差异
7、 找出 差异, 如某个input框发生了变化
8、 只用新的DOM中的input元素, 替换掉老的DOM中的input元素
缺陷:
性能的提升并不明显
第三种方式: 采用虚拟DOM
1、 state数据
2、 JSX 模板
3、 数据 + 模板 生成虚拟DOM( 虚拟DOM就是一个JS对象, 用它来描述真实的DOM)( 损耗了性能)
[‘div’, {id: ‘abc’}, [‘span’, {}, ‘hello world’]]
4、 用虚拟DOM的结构生成真实的DOM, 来显示
<div id="abc"><span>hello world</span></div>
5、 state发生变化
6、 数据 + 模板 生成新的虚拟DOM (极大的提升了性能)
[‘div’, {id: ‘abc’}, [‘span’, {}, ‘bye bye’]]
7、比较原始的虚拟DOM和新的虚拟DOM的区别,找到区别是span中的内容 (极大的提升了性能)
setState是异步的,可以将连续的数据变化合并成一次去更新
虚机DOM中的Diff算法
同层比较,先比较第一层,相同,则比较第二层;不相同则停止比较,重新渲染
简化比较算法
比对时根据key值比较,所以要给循环时的节点设key值,key不要用index,index会变化
比如:
item key
a 0
b 1
c 1
删除a
b 0
c 1
b c的key值变化了,跟之前的没有关联关系了
8、直接操作DOM,改变span中的内容
优点:
性能提升了
它使得跨端应用得以实现 React Native
render() {
//JSX ->JS对象(虚机DOM)->真实的DOM
return (
<div> //此处的<div>不是真实的html元素,是JSX语法中的元素,JSX是为了简化编程方式
item
</div>
)
等价于
//JSX ->createElement -> JS对象(虚机DOM)->真实的DOM
return React.createElement('div',{},'item');
}