React - review 2
一、虚拟 DOM
虚拟 DOM 就是一个 Js 对象,比较 Js 对象不怎么消耗性能,比较真实 DOM 消耗性能
- 数据更新,视图重新渲染
二、深入了解虚拟 DOM
- render 返回的内容是 JSX 模板 JSX -> JS 对象(虚拟 DOM) -> 真实的 DOM
render() {
return (
<div>
<div><input /><button>提交</button></div>
<ul>
<li>1</li>
<li>2</li>
</ul>
</div>
)
}
- JSX 是如何变成 JS 对象(虚拟 DOM)的?通过 createElement
即:JSX -> createElement -> JS 对象(虚拟 DOM) -> 真实的 DOM
- Test1
class Test extends Component {
render() {
return (
<div>你好</div>
)
}
}
class Test extends Component {
render() {
return (
// <div>你好</div>
React.createElement('div', {}, '你好')
)
}
}
- Test2
class Test extends Component {
render() {
return (
<div>
<span>你好</span>
</div>
)
}
}
class Test extends Component {
render() {
return (
// <div>
// <span>你好</span>
// </div>
React.createElement('div', {}, React.createElement('span', {}, "你好"))
)
}
}
- 优点:
1)性能提升了;
2)它使得跨域应用得以实现 React Native
三、虚拟 DOM 中的 Diff 算法
- Diff => difference 寻找原始虚拟 DOM 与 新的虚拟 DOM 之间的差异
- 当数据发生改变的时候,虚拟 DOM 会进行对比,寻找差异
- 为什么 React 中的 setstate 是一个异步函数?提高 React 底层的性能
=> 当调用 setstate 时,虚拟 DOM 就要进行比对,更新页面,如果连续调用 N 次 setstate ,页面会更新 N 次。如果连续调用 N 次 setstate,React 会把它们合并成一次,只进行一次 DOM 更新 - Diff 算法
=> 原始虚拟 DOM 与 新的虚拟 DOM 同层进行比较,当发现差异时,停止比较,将原始虚拟 DOM 全部替换成新的虚拟 DOM;
=> 同层比较的算法简单,提高了比较速度 - 当数据发生改变时,比如数组:
原始数组:[a, b, c, d, e]
原始数组:[a, b, c, d, e]
=> 为什么要有 key 值呢?
没有 key 值,在进行原始数组与新的数组进行比较时,每个节点没有自己的名字,节点与节点之间的关系就很难被确立,需要用多层循环进行比较,比较麻烦且消耗性能;
有 key 值,第一次循环的时候给每个节点加上名字,第二次循环的时候直接比对是否原始数组是否有相同的名字就可以了
=> 为什么 key 值最好不要用 index,最好用 item ?
index 不稳定,当我们删除 a 的时候,新的数组变成[b, c],而 b 的下标变成了0,c 的下标变成了1;
index | 0 | 1 | 2 |
---|---|---|---|
item | a | b | c |
index | 0 | 1 |
---|---|---|
item | b | c |