在react中,数据更新会驱动页面重新渲染,假设没有react,要我们自己去实现这个功能,我们会怎么做呢?
最简单的思路是这样的:
- state数据
- JSX模板
- 数据+模板,生成真实的DOM来显示
- state发生改变
- 数据+模板,生成真实的DOM,替换原始的DOM
但是这样的方案有个致命的缺陷:
- 第三步和第五步,非常耗性能,
那么如何做性能优化呢?结合实际开发经验,我们知道,很多时候,往往只是一部分DOM发生了改变,而不是整个,所以很自然的就能想到,在上一个方案中,我们缺少了一步对比DOM,只找出变化的DOM进行替换不就好了吗?
- state数据
- JSX模板
- 数据+模板,生成真实的DOM
- state改变
- 数据+模板,生成真实的DOM,对比原始的DOM
- 找出变化的DOM部分进行替换
改进的方案看似对第一种方案进行了优化,但实际上看第五步,生成真实的DOM,对比原始的DOM这一步依然很耗性能,相当于没优化。
接下来了解下react是如何进行优化的:
- state数据
- JSX模板
- 根据数据+模板,生成虚拟DOM(虚拟DOM就是一个用来描述真实DOM的JS对象)
- 用虚拟DOM的结构生成真实的DOM
- state改变
- 生成新的虚拟DOM,对比原始的虚拟DOM,找出变化的部分
- 直接操作DOM,改变变化部分的内容
在react的方案中,第六步极大的提升了性能,毕竟对比两个JS对象,要比对比两个DOM合适得多。
所以我们平时写的JSX,实际上就是一个模板,加上数据,生成了虚拟DOM,然后在生成真实的DOM。
在react底层,会将我们写的JSX,通过createElement()方法,转换成虚拟DOM(也就是js对象),然后生成真实DOM。
class App extends Component {
render() {
return (
<!--<div id="div1">123</div>-->
React.createElement('div', {id: 'div1'}, '123')
)
}
}
上述代码,与直接return出去一个div是一样的效果。