Skip to main content

深入了解虚拟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带来了哪些好处?

  1. 性能提升了(虚拟DOM对比而非真实DOM对比)
  2. 它使得跨端应用得以实现 - React Native(我们知道原生应用android和ios是没有DOM的,但是react有虚拟DOM,如果给网页用,我们就将虚拟DOM转化为真实DOM;如果给原生应用用的话就转化为原生应用的组件供android和ios使用)