深入了解虚拟DOM
回顾一下react底层实现原理:
- 1, state数据
- 2, JSX模版
- 3, 数据+模版结合,生成虚拟DOM(虚拟DOM就是一个js对象,用它来描述真实DOM) -- 损耗了性能
['div',{id:'abc'},['span',{},'hello world']]
(数组的三项分别对应着tag,属性,children) - 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力的内容 (极大的提升了性能)
- 8, 直接操作DOM,改变span中的内容
react会根据state和模版先生成虚拟DOM,然后再将虚拟DOM转化为真实DOM
JSX ==> createElement() ==> 虚拟DOM(JS对象) => 真实的DOM
为了方便说明,我们找个简单的案例:
import React, { PureComponent } from 'react'
export default class Test extends PureComponent {
render() {
return (
<div>Test</div>
)
}
}
render方法返回的JSX<div>Test</div>
不是真实DOM,react底层会用React.createElement()
api先将jsx转化为js对象
import React, { PureComponent } from 'react'
export default class Test extends PureComponent {
render() {
return React.createElement('div',{},'test') //tag 属性 children
}
}
这2种写法其实是等价的,只是React.createElement()
是更偏向底层的接口
接下来,我们来渲染稍微复杂点的DOM: <div><span>test</span></div>
,用React.createElement()
该怎么写呢?
import React, { PureComponent } from 'react'
export default class Test extends PureComponent {
render() {
return React.createElement('div',{}, React.createElement('span',{},'test'))
}
}
可以看到底层的这种写法很复杂,所以react推出了jsx的这种语法
虚拟DOM带来了哪些好处?
- 性能提升了(虚拟DOM对比而非真实DOM对比)
- 它使得跨端应用得以实现 - React Native(我们知道原生应用android和ios是没有DOM的,但是react有虚拟DOM,如果给网页用,我们就将虚拟DOM转化为真实DOM;如果给原生应用用的话就转化为原生应用的组件供android和ios使用)