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,来显示
<div id='abc'><span>hello world</span></div>

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

1547014058427.jpg
  • Diff算法会按照同层比较的方式进行比对
  • 如果第一层进行比对时就不一样,React就不会继续往下一层比对了,它会将原始的虚拟DOM下的节点全部删除,然后用重新生成节点下的虚拟DOM替换原始的虚拟DOM下的所有节点
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 (
            <div key={index}>
                <TodoItem
                    textContent={item} 
                    index={index}
                    deleteItem={this.handleItemDelete}
                />                  
            </div>
            )
    })      

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

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 161,326评论 4 369
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 68,228评论 1 304
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 110,979评论 0 252
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,489评论 0 217
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,894评论 3 294
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,900评论 1 224
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 32,075评论 2 317
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,803评论 0 205
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,565评论 1 249
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,778评论 2 253
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,255评论 1 265
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,582评论 3 261
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,254评论 3 241
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,151评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,952评论 0 201
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 36,035评论 2 285
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,839评论 2 277

推荐阅读更多精彩内容