React - review 2

一、虚拟 DOM

虚拟 DOM 就是一个 Js 对象,比较 Js 对象不怎么消耗性能,比较真实 DOM 消耗性能

  1. 数据更新,视图重新渲染
  • 第一种
  1. state 数据
  2. JSX 模板
  3. 数据 + 模板 结合,生成真实的DOM,来显示
  4. state 发生改变
  5. 数据 + 模板 结合,生成真实的DOM,替换原始的 DOM

      缺陷:第一次生成了完整的 DOM 碎片,第二次依然生成了完整的 DOM 碎片,再用第二次的 DOM 替换第一次的 DOM,非常耗性能

  • 第二种
  1. state 数据
  2. JSX 模板
  3. 数据 + 模板 结合,生成真实的DOM,来显示
  4. state 发生改变
  5. 数据 + 模板 结合,生成真实的DOM,并不直接替换原始的 DOM
  6. 新的 DOM (DoucumentFragment)和原始的 DOM 做对比,找差异
  7. 找出哪里发生了变化(假设 input 框发生了变化)
  8. 只用新的 DOM 中的 input 替换旧的 DOM 中的 input 即可

      缺陷:性能的提升并不明显

  • 第三种
  1. state 数据
  2. JSX 模板
  3. 数据 + 模板 生成虚拟DOM(虚拟 DOM 就是一个 Js 对象,用它来描述真实 DOM)=> 消耗了性能(极小)
    ['div', {id: 'box'}, ['span', {}, 'Hi React']
  4. 用虚拟 DOM 的结构生成真实的 DOM,来显示
    <div id ="box"><span>Hi React</span></div>
  5. state 发生改变
  6. 数据 + 模板 结合,生成新的虚拟 DOM (极大的提升了性能)
    <div id ="box"><span>Bye React</span></div>
  7. 比较原始虚拟 DOM 和新的虚拟 DOM 的区别, 找到区别是 span 中的内容发生了改变(极大的提升了性能)
  8. 直接操作 DOM ,改变 span 中的内容

二、深入了解虚拟 DOM

  1. render 返回的内容是 JSX 模板 JSX -> JS 对象(虚拟 DOM) -> 真实的 DOM
render() {
    return (
        <div>
            <div><input /><button>提交</button></div>
            <ul>
                <li>1</li>
                <li>2</li>
            </ul>
        </div>
    )
}
  1. 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. 优点:
    1)性能提升了;
    2)它使得跨域应用得以实现 React Native

三、虚拟 DOM 中的 Diff 算法

  1. Diff => difference 寻找原始虚拟 DOM 与 新的虚拟 DOM 之间的差异
  2. 当数据发生改变的时候,虚拟 DOM 会进行对比,寻找差异
导致
如何比较
数据发生改变
虚拟 DOM 会进行比较, 寻找差异
调用setstate
props发生改变
state发生改变
Diff 算法进行比较
  1. 为什么 React 中的 setstate 是一个异步函数?提高 React 底层的性能
    => 当调用 setstate 时,虚拟 DOM 就要进行比对,更新页面,如果连续调用 N 次 setstate ,页面会更新 N 次。如果连续调用 N 次 setstate,React 会把它们合并成一次,只进行一次 DOM 更新
  2. Diff 算法
    在这里插入图片描述
    => 原始虚拟 DOM 与 新的虚拟 DOM 同层进行比较,当发现差异时,停止比较,将原始虚拟 DOM 全部替换成新的虚拟 DOM;
    => 同层比较的算法简单,提高了比较速度
  3. 当数据发生改变时,比如数组:
    原始数组:[a, b, c, d, e]
    原始数组:[a, b, c, d, e]
    在这里插入图片描述
    => 为什么要有 key 值呢?
         没有 key 值,在进行原始数组与新的数组进行比较时,每个节点没有自己的名字,节点与节点之间的关系就很难被确立,需要用多层循环进行比较,比较麻烦且消耗性能;
         有 key 值,第一次循环的时候给每个节点加上名字,第二次循环的时候直接比对是否原始数组是否有相同的名字就可以了
    => 为什么 key 值最好不要用 index,最好用 item ?
         index 不稳定,当我们删除 a 的时候,新的数组变成[b, c],而 b 的下标变成了0,c 的下标变成了1;
index012
itemabc
index01
itembc
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值