React学习笔记(二)

state, props,render()

为什么说React是由数据驱动的?

  • 当组件的state或者props发生改变时,render函数就会被执行,而页面又是由render函数渲染出来的,因此说,数据一旦改变页面就会随之改变
  • 当父组件的render函数被执行时,它的子组件的render函数也会被执行一次

虚拟DOM

React中的render()函数执行效率是非常高的,原因在于React中使用了虚拟DOM

  • 原因:减少了JS中创建真实DOM的性能损耗,取而代之的是创建虚拟DOM,就是JS对象,另外在进行对比时减去了真实DOM的对比,取而代之的是虚拟DOM即JS对象的对比,从而提高了性能

1 生成state数据
2 JSX模版

3 生成虚拟DOM(虚拟DOM就是一个JS数组对象,用它来描述真实DOM) --此处会带来一些新能损耗,但是JS生成一个对象性能损耗是很小的,如果用JS生成一个DOM,会使用webApplication的API,这种性能损耗是很大的
['div', {id: 'abc'}, ['span',{ }, 'hello world']]

4 用虚拟DOM生成真实的DOM,来显示

hello world

5 state 发生变化
6 数据 + 模版 生成新的虚拟DOM
['div', {id: 'abc'}, ['span',{ }, 'bye bye']]
7 比较原始虚拟DOM和新的虚拟DOM的区别,找到区别是span中的内容
8 直接操作DOM 改变span中的内容

JSX模版生成真实DOM流程

  • JSX代码就是一个模版,并不是真实的DOM,之后React会将模版与state结合,最终生成一个虚拟DOM即JS对象,之后才会生成真实DOM
  • jSX -> JS对象 -> 真实DOM

JSX底层如何被转为JS对象?最终又是如何变为真实DOM?

  • 使用了React.createElement('div',{属性},'item') ,将一个对象传给createElement函数,函数内部首先会生成一个虚拟DOM,最终渲染成真实的DOM
  • jSX -> createElement函数 -> 虚拟DOM(JS对象) -> 真实DOM

虚拟DOM的优点

  • 提升了性能
  • 得以实现跨端应用(例如RN,得益于虚拟DOM才能实现原生应用,因为如果没有虚拟DOM,当使用JSX模版和数据结合后去直接渲染真实DOM,在浏览器中是没有问题的,在手机端是不存在DOM这个概念的,因此手机端是无法使用的;当使用了虚拟DOM后,JS对象是可以被手机端识别的,在PC端最终会生成真实DOM,在手机端不会生成真实的DOM,而是生成一些原生的组件)

虚拟DOM中的Diff(Difference)算法

此算法针对上述步骤中的第7步,即比较原始虚拟DOM和新的虚拟DOM的区别,可以提高比对性能

  • React底层在调用了setState方法时,才会出发Diff算法(setState方法是异步执行的)

问题:为什么setState方法会被React设计成一个异步方法?
场景:如果在很短时间间隔内,连续调用了3次setState方法,那么React底层可能会调用3次Diff算法进行比对,这样会很消耗性能
React实现:会将这3次调用setState方法合并为只调用一次setState方法,即只做一次虚拟DOM的比对,然后更新一次DOM

React学习笔记(二)_第1张图片
1547014058427.jpg
  • Diff算法会按照同层比较的方式进行比对
  • 如果第一层进行比对时就不一样,React就不会继续往下一层比对了,它会将原始的虚拟DOM下的节点全部删除,然后用重新生成节点下的虚拟DOM替换原始的虚拟DOM下的所有节点
React学习笔记(二)_第2张图片
1547014477063.jpg
  • 在虚拟DOM比对时,每个节点都会有一个key值,这样便于与新的虚拟DOM进行比对
  • 也是为什么在做循环操作时,不要省略key值,这样就无法保证在原始虚拟DOM中的key值与新的虚拟DOM的key值保持一致
  • 例如在如下循环中,使用了index作为key值时,此时输入a,b,c
    a 对应key值为0 b对应key值为1 c对应key值为2
    当删除a时,此时 b对应key值为0 ,c对应key值为1
    那么此时,b之前的key值是1,当前b的key值是0 ,所以就没有办法建立起关系了
    这就是用index作为key值的一个问题,会导致key值不稳定
    return this.state.list.map((item,index) => {
        return (
            
) })

总结: 同层比较和key值比较都是diff算法的一部分

你可能感兴趣的:(React学习笔记(二))