最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺談React底層實(shí)現(xiàn)原理

 更新時(shí)間:2022年07月15日 09:26:38   作者:杉菜醬_  
本文主要介紹了淺談React底層實(shí)現(xiàn)原理,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

1. props,state與render函數(shù)關(guān)系,數(shù)據(jù)和頁面如何實(shí)現(xiàn)互相聯(lián)動?

當(dāng)組件的state或者props發(fā)生改變的時(shí)候,自己的render函數(shù)就會重新執(zhí)行。
注意:當(dāng)父組件的render被執(zhí)行的時(shí)候,子組件的render也會被重新執(zhí)行一次(因?yàn)樵诟附M件的render里面)。
即當(dāng)綁定的事件改變了state或者props,render函數(shù)就會重新執(zhí)行解析頁面,這時(shí)解析的時(shí)候就會使用新的數(shù)據(jù)了,所以頁面就會變化。

2. React中的虛擬DOM

因?yàn)橹灰猻tate、props改變就會重新渲染render,可以想象要不斷的重新渲染頁面對性能要求非常高,實(shí)際上render的性能時(shí)非常高的,這歸功于虛擬DOM。
首先提前明確DOM的相關(guān)操作需要調(diào)用web application對性能損耗是比較高的。

常規(guī)思路

  • state數(shù)據(jù)
  • JSX模板
  • 數(shù)據(jù)+模板相結(jié)合,生成真實(shí)的DOM來展示。
  • state改變
  • 數(shù)據(jù)+模板相結(jié)合,生成真實(shí)的DOM,替換原始的DOM
    缺點(diǎn):第一次生成了一個(gè)完整的DOM片段,第二次又生成了一個(gè)完整的DOM片段,第二次的DOM替換第一次的DOM,這樣生成、替換非常的消耗性能。

改良思路(仍使用DOM)

  • state數(shù)據(jù)
  • JSX模板
  • 數(shù)據(jù)+模板相結(jié)合,生成真實(shí)的DOM來展示
  • state改變
  • 數(shù)據(jù)+模板相結(jié)合,生成真實(shí)的DOM,并不直接替換原始的DOM
  • 新的DOM(文檔碎片)原始的DOM作對比,找差異(性能損耗大)
  • 找出發(fā)生了什么變化,比如找出了只有input框有差異
  • 只用新的DOM中的input元素替換掉老的DOM中的input元素
    缺點(diǎn):性能提升并不明顯,因?yàn)樾阅芟脑诹藢Ρ壬稀?/li>

React的思路

  • state數(shù)據(jù)
  • JSX模板
  • 數(shù)據(jù)+模板相結(jié)合,生成虛擬DOM(虛擬DOM就是一個(gè)JS數(shù)組對象,完整的描述真實(shí)的DOM)( [ ‘ idv ‘ , { id : ‘ abc ‘ } , [ ‘ span ‘ , { } , ‘ hello ‘ ] ] ),用JS生成JS對象性能損耗極小,生成DOM性能損耗大要調(diào)用web application。
  • 用虛擬DOM的結(jié)構(gòu)生成真實(shí)的DOM,來顯示( < div id=’abc’>< span>hello</ span></ div> )。
  • state發(fā)生變化(< div id=’abc’>< span>bye</ span></ div>)
  • 數(shù)組+模板生成了新的虛擬DOM( [ ‘ idv ‘ , { id : ‘ abc ‘ } , [ ‘ span ‘ , { } , ‘ bye ‘ ] ] )(極大的提升了性能)
  • 比較原始虛擬DOM和新的虛擬DOM的區(qū)別,找到區(qū)別是span中的內(nèi)容(極大的提升了性能)
  • 直接操作DOM改變span中的內(nèi)容
    總結(jié):減少了對真實(shí)DOM的創(chuàng)建和對比,而創(chuàng)建和對比的是JS對象,從而實(shí)現(xiàn)了極大的性能飛躍。

深入理解虛擬DOM

Vue與React中的虛擬DOM的原理和步驟是完全一致的。
React中真實(shí)DOM的生成步驟:JSX -> createElement方法 -> JS對象(虛擬DOM) -> 真實(shí)的DOM。
因此可見,JSX中的div等標(biāo)簽僅僅是JSX的語法,并不是DOM,僅用于生成JS對象。
其實(shí)在React中創(chuàng)建虛擬DOM(JS對象)使用的是(沒有JSX語法也可用下面的方法生成)

// 傳三個(gè)參數(shù):標(biāo)簽 屬性 內(nèi)容
// <div>item</div>
// 所以其實(shí)沒有JSX語法也可以用下面的方式生成
React.createElement('div',{},'item')

虛擬DOM的優(yōu)點(diǎn):

  • 性能提升DOM對比變成了JS的對比
  • 它使得跨平臺應(yīng)用得以實(shí)現(xiàn),React Native(安卓和ios中沒有DOM的概念,使用虛擬DOM(JS對象)在所有應(yīng)用中都可以被使用,然后變成原生客戶端的組件)

3. 虛擬DOM的diff算法

  • Diff算法用于比較原始虛擬DOM和新的虛擬DOM的區(qū)別,即兩個(gè)JS對象該如何比對。
  • diff算法全稱為difference算法
  • setState實(shí)際上是異步的,這是為了提升react底層的性能,是為了防止時(shí)間間隔很短的情況下多次改變state,React會在這種情況下將幾次改變state合并成一次從而提高性能。
  • diff算法是同級比較,假設(shè)第一層兩個(gè)虛擬DOM節(jié)點(diǎn)不一致,就不會往下比了,就會將原始頁面虛擬DOM全部刪除掉,然后用新的虛擬DOM進(jìn)行全部的替換,雖然有可能有一些性能的浪費(fèi),但是由于同層對比的算法性能很高,因此又彌補(bǔ)了性能的損耗。
  • 做list循環(huán)的時(shí)候有一個(gè)key值,這樣比對的時(shí)候就可以相對應(yīng)的比對,找出要改變的,以及不需要渲染的,這樣使用key做關(guān)聯(lián),極大地提升了虛擬DOM比對的性能,這要保證在新的虛擬DOM后key值不變,這就說明了為什么做list循環(huán)的時(shí)候key的值不要是index,因?yàn)檫@樣沒有辦法保證原虛擬DOM和新虛擬DOM的key值一致性,而造成性能的損耗,一般這個(gè)key對應(yīng)后臺數(shù)據(jù)的唯一id字段,而不是循環(huán)的index。

4. React中ref的使用

  • 在react中使用ref來操作DOM
  • 在react中也可以使用e.target來獲取DOM
  • ref這個(gè)參數(shù)是一個(gè)函數(shù)
<input
? ? id = "insertArea"
? ? className="input"
? ? value={this.state.inputValue}
? ? onChange={this.handleInputChange}
? ? ref={(input)=>{this.input = input}}
/>

handleInputChange(e){
?? ?// const value = e.target.value; // 原始的方法
?? ?const value = this.input.value;
?? ?this.setState(() => ({
?? ??? ?inputValue: value
?? ?}))
}

一般情況下不推薦使用ref這種方法,因?yàn)閟etState是一個(gè)異步函數(shù),因此去操作DOM的時(shí)候可能無法正確的輸出頁面的最新DOM情況,有時(shí)候比較復(fù)雜的操作如動畫之類的,如果一定要使用,就需要在setState的第二個(gè)函數(shù),這個(gè)是回調(diào)函數(shù),在setState完成的時(shí)候觸發(fā)。

handleBtnClick(e){
    this.setState((prevState)=>({
        list: [...prevState.list, prevState.inputValue], // 展開運(yùn)算符
        inputValue: '',
    }), ()=>{
        console.log(this.ul.querySelectorAll('div').length);
    });
}

5. React中的生命周期函數(shù)

  • 生命周期函數(shù)是指在某一個(gè)時(shí)刻組件會自動調(diào)用執(zhí)行的函數(shù)。
  • render函數(shù)就是一個(gè)生命周期函數(shù)的例子,當(dāng)state或props的時(shí)候改變的時(shí)刻就會自動執(zhí)行。
  • contructor 可以理解成一個(gè)生命周期函數(shù),在組件被創(chuàng)建的時(shí)候就會被執(zhí)行,但是它是es6語法,不是react特殊的語法。

組件掛載的過程:

  • componentWillMount 在組件即將被掛載到頁面的時(shí)刻自動執(zhí)行,在渲染之前被執(zhí)行
  • render 進(jìn)行掛載,是必須存在的
  • componentDidMount 在組件被掛載到頁面之后被執(zhí)行。
  • 注意:在state和props 改變的時(shí)候只有render會執(zhí)行,componentWillMount和componentDidMount不會執(zhí)行,他們只會在第一次掛載到頁面的時(shí)候被執(zhí)行。
  • 組件更新:
  • componentWillReceiveProps 兩個(gè)條件都要滿足:1. 當(dāng)一個(gè)組件從父組件接收參數(shù) 2. 如果這個(gè)組件第一次存在于父組件中不會執(zhí)行,如果這個(gè)組件之前已經(jīng)存在于父組件中,才會執(zhí)行。
  • shouldComponentUpdate 組件即將被更新之前會執(zhí)行,如焦點(diǎn)input框的時(shí)候,會返回一個(gè)true和false來判斷要不要更新。
  • componentWillUpdate 組件更新之前會自動執(zhí)行,在shouldComponent返回true之后才會執(zhí)行。
  • componentDidUpdate 組件更新完成之后被執(zhí)行。
  • 組件去除的過程:
  • componentWillUnmount:但這個(gè)組件即將被從頁面中剔除的時(shí)候執(zhí)行。

6. 生命周期函數(shù)的使用場景

  • 防止父組件render的時(shí)候,子組件也要render,從而提升性能。
  • shouldComponentUpdate(nextProps,nextState){if(nextProps.content !== this.props.content){return true} return false}
  • 頁面初始化的時(shí)候,在componentDidMount中發(fā)送AJAX請求(推薦),或者在constructor中,千萬不要放在render里面,會造成死循環(huán),也最好不要在componentWillMount中發(fā)送ajax,放這里面是沒有問題的,但是如果在react native 中會有問題。
  • react 沒有內(nèi)置ajax,使用axios。

到此這篇關(guān)于淺談React底層實(shí)現(xiàn)原理的文章就介紹到這了,更多相關(guān)React底層內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • React高級概念之Context用法詳解

    React高級概念之Context用法詳解

    在React應(yīng)用中,為了讓數(shù)據(jù)在組件間共享,常見的方式是讓它們以props的形式自頂向下傳遞,如果數(shù)據(jù)要在組件樹不同層級共享,那么這些數(shù)據(jù)必須逐層傳遞直到目的地,Context如同管道,它將數(shù)據(jù)從入口直接傳遞到出口,使用Context能避免“prop-drilling”
    2023-06-06
  • React父子組件傳值(組件通信)的實(shí)現(xiàn)方法

    React父子組件傳值(組件通信)的實(shí)現(xiàn)方法

    本文主要介紹了React父子組件傳值(組件通信)的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2022-05-05
  • React 路由傳參的幾種實(shí)現(xiàn)方法

    React 路由傳參的幾種實(shí)現(xiàn)方法

    React中傳參方式有很多,通過路由傳參的方式也是必不可少的一種,本文主要介紹了React路由傳參的幾種實(shí)現(xiàn)方法,具有一定的參考價(jià)值,感興趣的可以了解一下
    2023-12-12
  • React?跨端動態(tài)化核心技術(shù)實(shí)例分析

    React?跨端動態(tài)化核心技術(shù)實(shí)例分析

    這篇文章主要為大家介紹了React?跨端動態(tài)化核心技術(shù)實(shí)例分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-10-10
  • Input標(biāo)簽自動校驗(yàn)功能去除實(shí)現(xiàn)

    Input標(biāo)簽自動校驗(yàn)功能去除實(shí)現(xiàn)

    這篇文章主要為大家介紹了Input標(biāo)簽的自動拼寫檢查功能去除實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-07-07
  • react滾動加載useInfiniteScroll?詳解

    react滾動加載useInfiniteScroll?詳解

    使用useInfiniteScroll?hook可以處理檢測用戶何時(shí)滾動到頁面底部的邏輯,并觸發(fā)回調(diào)函數(shù)以加載更多數(shù)據(jù),它還提供了一種簡單的方法來管理加載和錯誤消息的狀態(tài),今天通過實(shí)例代碼介紹下react滾動加載useInfiniteScroll?相關(guān)知識,感興趣的朋友跟隨小編一起看看吧
    2023-09-09
  • 詳解React中的setState執(zhí)行機(jī)制

    詳解React中的setState執(zhí)行機(jī)制

    setState是React組件中用于更新狀態(tài)的方法,是類組件中的方法,用于更新組件的狀態(tài)并重新渲染組件,本文給大家詳細(xì)介紹了React中的setState執(zhí)行機(jī)制,文中通過代碼示例介紹的非常詳細(xì),需要的朋友可以參考下
    2023-12-12
  • react native仿微信PopupWindow效果的實(shí)例代碼

    react native仿微信PopupWindow效果的實(shí)例代碼

    本篇文章主要介紹了react native仿微信PopupWindow效果的實(shí)例代碼,具有一定的參考價(jià)值,有興趣的可以了解一下
    2017-08-08
  • React拖拽調(diào)整大小的組件

    React拖拽調(diào)整大小的組件

    這篇文章主要為大家詳細(xì)介紹了React拖拽調(diào)整大小的組件,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08
  • React的組件協(xié)同使用實(shí)現(xiàn)方式

    React的組件協(xié)同使用實(shí)現(xiàn)方式

    這篇文章主要介紹了React的組件協(xié)同使用,文中給大家提到在React開發(fā)中,有哪些場景的組件協(xié)同?又如何去實(shí)現(xiàn)組件的協(xié)同使用呢?本文都給大家提到,感興趣的朋友跟隨小編一起看看吧
    2021-09-09

最新評論

博乐市| 启东市| 剑阁县| 运城市| 宜春市| 青州市| 盐城市| 叶城县| 正安县| 揭西县| 旌德县| 延寿县| 德令哈市| 沈丘县| 文昌市| 微山县| 玉树县| 汝州市| 汾阳市| 余庆县| 武川县| 濮阳县| 平利县| 耒阳市| 甘德县| 土默特左旗| 菏泽市| 北宁市| 南澳县| 巴彦淖尔市| 赫章县| 石嘴山市| 乐亭县| 句容市| 祁阳县| 镇远县| 青龙| 鄄城县| 大竹县| 保山市| 元谋县|