赞
踩
本章内容
上一节我们讲了 state、props与render函数的关系,本节内容开始了解 React中的”虚拟 DOM“ 相关知识。
state或者 props变化时,render函数会重新知己,界面也重新被渲染。React, 我们要实现数据变化界面也随着变化,通常可以这么做方式一: 1、定义一个 state 数据 2、定义一个 ”JSX模版“ 3、将”数据+JSX模版“结合,生成真实 DOM 来显示 4、当数据变化时 5、”数据+JSX模版“相结合,生成真实DOM,替换原始 DOM 6、如此往复循环 4、5步骤 方式二:(对方式一进行优化下,不直接替换旧的 DOM,只替换变化的数据节点) 1、定义一个 state 数据 2、定义一个 ”JSX模版“ 3、将”数据+JSX模版“结合,生成真实 DOM 来显示 4、当数据变化时 5、”数据+JSX模版“相结合,生成真实 DOM 6、新的 DOM 和旧 DOM比对,找到只变化的节点 7、用新 DOM 变化的节点替换旧 DOM 变化处的节点 8、如此往复循环 5、6、7步骤 方式二相对于方式一的步骤增加了,但是性能会有所提升(局部替换比整体替换消耗的性能更少),但是方式二的比较过程同样耗费了些性能,这样来看,性能也没提升多少
基于上述的痛点,
React提出了”虚拟 DOM“的方案。也就是方式三:
state数据this.state = {
content: 'hello'
}
JSX 模版render() {
return (
<div id="d1">
<span>{content}</span>
</div>
)
}
React底层会调用 React.createElement()接口,将 JSX 模版变成一个原始的”虚拟DOM“(虚拟DOM 本质是一个数组形式的 JS对象,用它来描述”真实的DOM“)虚拟 DOM 格式:[标签名,标签属性,标签的子节点]
注意如果标签子节点又是一个完整的 DOM,那么还是遵循 ”[标签名,标签属性,标签的子节点]“ 的格式
那将 2中的”JSX模版“转为”JS对象“的底层实现。运行后发现,我们可以通过 React.createElement()来实现 JSX的功能。唯一的缺点就是很复杂,所以这也是为什么 JSX存在的原因,它是一个更加简便好用的方式
// 1、注释掉这里,改用下面的 React.createElement方式实现
// render() {
// return (
// <div id="d1">
// <span>{content}</span>
// </div>
// )
// }
// 2、使用 React.createElement方式实现上面注释的功能
render() {
// 我们将“JSX 模板”用 craeteElement 方法来改写,其接收 3 个参数依次是:元素的标签名、标签的属性、元素的children 子节点
return React.createElement("div", {id: "d1", React.createElement("span", {}, "hello")})
}
上面生成的”虚拟DOM“为:["div", {id: "d1"}, ["span", {}, "hello"]]
<div id="d1">
<span>{content}</span>
</div>
state变化this.state = {
content: 'hello world'
}
6、重复 3步骤,生成新的”虚拟DOM“: ["div", {id: "d1"}, ["span", {}, "hello world"]]
7、比较”旧的虚拟DOM“和”新的虚拟DOM“,找到 span中的内容是有变更的
8、直接操作 DOM,改变 span里的内容
”虚拟DOM“本质上是用 JS生成的一个 JS对象,这个转变消耗的性能较少。如果直接使用 JS生成一个 DOM元素,那么它是会底层调用 Web Application的API,性能消耗极大
然后两个”虚拟DOM“之间比对,本质是 js对象的比对,其底层使用的”Diff算法“是不怎么消耗性能的。如果直接把两个”真实 DOM“进行比对,其性能消耗极大
”JS 对象“不仅可以让”浏览器“识别,在原生应用(Android IOS)上也可以(注意:”原生应用“里不存在 DOM的概念,所以真实的 DOM在原生应用中不被识别,无法使用),因此,有了”虚拟DOM“后,我们用它生成一些原生组件。
这样的话,在复用”state“、”JSX模版“等代码优势下,让”虚拟DOM“在不同”端“中进行转化:网页端转化为”真实DOM“,原生应用中转化为原生的”组件“
到此,本章内容结束!
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。