最近,我研究了Facebook的React框架。它使用了一个叫做“虚拟DOM”的概念,我并不真正理解这个概念。
什么是虚拟DOM?它的优点是什么?
最近,我研究了Facebook的React框架。它使用了一个叫做“虚拟DOM”的概念,我并不真正理解这个概念。
什么是虚拟DOM?它的优点是什么?
当前回答
虚拟Dom是创建Dom的一个副本。虚拟dom与dom比较,虚拟dom只更新dom中发生变化的部分。它没有渲染整个dom它只是改变了dom中dom的更新部分。这是非常耗时的,从这个功能,我们的应用程序工作得很快。
其他回答
让我们举个例子——虽然是一个很天真的例子:如果你家里的房间里有什么乱七八糟的东西,你需要清理它,你的第一步会是什么?你是要打扫你乱糟糟的房间,还是要打扫整个房子?答案肯定是,你只打扫需要打扫的房间。这就是虚拟DOM的作用。
普通JS遍历或呈现整个DOM,而不是只呈现需要更改的部分。
所以当你有任何变化时,比如你想要添加另一个<div>到你的DOM,那么虚拟DOM将被创建,它实际上不会对实际DOM做任何改变。现在使用这个虚拟DOM,您将检查它与当前DOM之间的区别。并且只有不同的部分(在本例中是新的<div>)将被添加,而不是重新渲染整个DOM。
这是一个简洁的概念:不直接操作DOM(容易出错并且依赖于可变状态),而是输出一个名为Virtual DOM的值。然后,虚拟DOM与DOM的当前状态进行区分,这会生成一个DOM操作列表,使当前DOM看起来像新DOM。这些操作在批量中快速应用。
从这里拍的。
React创建了一个自定义对象树,表示DOM的一部分。例如,它不是创建一个包含UL元素的实际DIV元素,而是创建一个React。包含React的div对象。ul对象。它可以非常快速地操作这些对象,而无需实际接触真正的DOM或通过DOM API。然后,当它呈现一个组件时,它使用这个虚拟DOM来确定它需要对真实DOM做什么,以使两棵树匹配。
您可以将虚拟DOM看作是一个蓝图。它包含了构建DOM所需的所有细节,但由于它不需要真正DOM中所有的重量级部分,因此可以更容易地创建和更改它。
根据React doc: https://reactjs.org/docs/faq-internals.html#what-is-the-virtual-dom
在React世界中,术语“虚拟DOM”通常与React元素相关,因为它们是代表用户界面的对象。
import React, { Component } from 'react'; //You need to do this inside a module to import
class App extends Component{
render(){
return (
<button>Hi</button> //This returns a virtual DOM
)
}
}
return里面的代码实际上是对函数React.createElement的调用:
//render can be rewritten like this:
render(){
return [
React.createElement(
'button',
{
key: null,
ref: null,
},
'Hi',
)
]
}
返回如下内容:
{
$$typeof: Symbol.for('react.element'),
type: "button",
key: null,
ref: null,
props: {
children: 'Hi',
}
}
这是虚拟DOM。它是一个JavaScript对象,操作成本比创建的实际DOM元素低得多
document.createElement('button');
它也是一个JavaScript对象,看起来像这样:
accessKey: ""
ariaAtomic: null
ariaAutoComplete: null
ariaBusy: null
ariaChecked: null
ariaColCount: null
ariaColIndex: null
ariaColSpan: null
ariaCurrent: null
ariaDescription: null
ariaDisabled: null
ariaExpanded: null
ariaHasPopup: null
ariaHidden: null
ariaKeyShortcuts: null
ariaLabel: null
ariaLevel: null
ariaLive: null
ariaModal: null
ariaMultiLine: null
ariaMultiSelectable: null
ariaOrientation: null
ariaPlaceholder: null
ariaPosInSet: null
ariaPressed: null
ariaReadOnly: null
ariaRelevant: null
ariaRequired: null
ariaRoleDescription: null
ariaRowCount: null
ariaRowIndex: null
ariaRowSpan: null
ariaSelected: null
ariaSetSize: null
ariaSort: null
ariaValueMax: null
ariaValueMin: null
ariaValueNow: null
ariaValueText: null
assignedSlot: null
attributeStyleMap: StylePropertyMap {size: 0}
attributes: NamedNodeMap {length: 0}
autocapitalize: ""
autofocus: false
baseURI: "http://localhost:3000/"
childElementCount: 0
childNodes: NodeList []
children: HTMLCollection []
classList: DOMTokenList [value: ""]
className: ""
clientHeight: 0
clientLeft: 0
clientTop: 0
clientWidth: 0
contentEditable: "inherit"
dataset: DOMStringMap {}
dir: ""
disabled: false
draggable: false
elementTiming: ""
enterKeyHint: ""
firstChild: null
firstElementChild: null
form: null
formAction: "http://localhost:3000/"
formEnctype: ""
formMethod: ""
formNoValidate: false
formTarget: ""
hidden: false
id: ""
innerHTML: ""
innerText: ""
inputMode: ""
isConnected: false
isContentEditable: false
labels: NodeList []
lang: ""
lastChild: null
lastElementChild: null
localName: "button"
name: ""
namespaceURI: "http://www.w3.org/1999/xhtml"
nextElementSibling: null
nextSibling: null
nodeName: "BUTTON"
nodeType: 1
nodeValue: null
nonce: ""
offsetHeight: 0
offsetLeft: 0
offsetParent: null
offsetTop: 0
offsetWidth: 0
onabort: null
onanimationend: null
onanimationiteration: null
onanimationstart: null
onauxclick: null
onbeforecopy: null
onbeforecut: null
onbeforepaste: null
onbeforexrselect: null
onblur: null
oncancel: null
oncanplay: null
oncanplaythrough: null
onchange: null
onclick: null
onclose: null
oncontextmenu: null
oncopy: null
oncuechange: null
oncut: null
ondblclick: null
ondrag: null
ondragend: null
ondragenter: null
ondragleave: null
ondragover: null
ondragstart: null
ondrop: null
ondurationchange: null
onemptied: null
onended: null
onerror: null
onfocus: null
onformdata: null
onfullscreenchange: null
onfullscreenerror: null
ongotpointercapture: null
oninput: null
oninvalid: null
onkeydown: null
onkeypress: null
onkeyup: null
onload: null
onloadeddata: null
onloadedmetadata: null
onloadstart: null
onlostpointercapture: null
onmousedown: null
onmouseenter: null
onmouseleave: null
onmousemove: null
onmouseout: null
onmouseover: null
onmouseup: null
onmousewheel: null
onpaste: null
onpause: null
onplay: null
onplaying: null
onpointercancel: null
onpointerdown: null
onpointerenter: null
onpointerleave: null
onpointermove: null
onpointerout: null
onpointerover: null
onpointerrawupdate: null
onpointerup: null
onprogress: null
onratechange: null
onreset: null
onresize: null
onscroll: null
onsearch: null
onseeked: null
onseeking: null
onselect: null
onselectionchange: null
onselectstart: null
onstalled: null
onsubmit: null
onsuspend: null
ontimeupdate: null
ontoggle: null
ontransitionend: null
onvolumechange: null
onwaiting: null
onwebkitanimationend: null
onwebkitanimationiteration: null
onwebkitanimationstart: null
onwebkitfullscreenchange: null
onwebkitfullscreenerror: null
onwebkittransitionend: null
onwheel: null
outerHTML: "<button></button>"
outerText: ""
ownerDocument: document
parentElement: null
parentNode: null
part: DOMTokenList [value: ""]
prefix: null
previousElementSibling: null
previousSibling: null
scrollHeight: 0
scrollLeft: 0
scrollTop: 0
scrollWidth: 0
shadowRoot: null
slot: ""
spellcheck: true
style: CSSStyleDeclaration {alignContent: "", alignItems: "", alignSelf: "", alignmentBaseline: "", all: "", …}
tabIndex: 0
tagName: "BUTTON"
textContent: ""
title: ""
translate: true
type: "submit"
validationMessage: ""
validity: ValidityState {valueMissing: false, typeMismatch: false, patternMismatch: false, tooLong: false, tooShort: false, …}
value: ""
willValidate: true
你可以在https://indepth.dev/inside-fiber-in-depth-overview-of-the-new-reconciliation-algorithm-in-react/上了解更多关于虚拟DOM和React的知识
虚拟Dom是创建Dom的一个副本。虚拟dom与dom比较,虚拟dom只更新dom中发生变化的部分。它没有渲染整个dom它只是改变了dom中dom的更新部分。这是非常耗时的,从这个功能,我们的应用程序工作得很快。