中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當(dāng)前位置: 首頁 > news >正文

網(wǎng)站怎么做彈幕播放器最好的免費(fèi)建站網(wǎng)站

網(wǎng)站怎么做彈幕播放器,最好的免費(fèi)建站網(wǎng)站,網(wǎng)站鼠標(biāo)經(jīng)過圖片代碼,微信小程序注冊(cè)費(fèi)用概述 react 在渲染過程中要做很多事情,所以不可能直接通過初始元素直接渲染還需要一個(gè)東西,就是虛擬節(jié)點(diǎn),暫不涉及React Fiber的概念,將vDom樹和Fiber 樹統(tǒng)稱為虛擬節(jié)點(diǎn)有了初始元素后,React 就會(huì)根據(jù)初始元素和其他可…

概述

  • react 在渲染過程中要做很多事情,所以不可能直接通過初始元素直接渲染
  • 還需要一個(gè)東西,就是虛擬節(jié)點(diǎn),暫不涉及React Fiber的概念,將vDom樹和Fiber 樹統(tǒng)稱為虛擬節(jié)點(diǎn)
  • 有了初始元素后,React 就會(huì)根據(jù)初始元素和其他可以生成虛擬節(jié)點(diǎn)的東西生成虛擬節(jié)點(diǎn)
  • React一定是通過虛擬節(jié)點(diǎn)來進(jìn)行渲染的

常用節(jié)點(diǎn)類型

  • 除了初始元素能生成虛擬節(jié)點(diǎn)以外,還有哪些可能生成虛擬節(jié)點(diǎn)?總共有多少節(jié)點(diǎn)類型?

1. Dom節(jié)點(diǎn) (ReactDomComponent)

  • 此dom非彼dom, 這里的dom指的是虛擬dom節(jié)點(diǎn),當(dāng)初始化元素的type屬性為字符串的時(shí)候
  • React 就會(huì)創(chuàng)建虛擬dom節(jié)點(diǎn),例如,前面使用 jsx 直接書寫的 const B = <div></div>
  • 它的屬性就是div, 可以打印出來 { type: 'div' }

2. 組件節(jié)點(diǎn) (ReactComposite)

  • class組件和函數(shù)式組件
  • type 有兩類:class App 或 f Test() 這種舉例

3. 文本節(jié)點(diǎn) (ReactTextNode)

  • 直接書寫字符串或數(shù)字,React 會(huì)創(chuàng)建為文本節(jié)點(diǎn)
  • 比如,我們可以直接用 ReactDOM.render 方法直接渲染字符串或數(shù)字
    import ReactDOM from 'react-dom/client';const root = ReactDOM.createRoot(document.getElementById('root'));// root.render('一頭豬') // 創(chuàng)建文本節(jié)點(diǎn)
    root.render(1111); // 創(chuàng)建文本節(jié)點(diǎn)
    

4. 空節(jié)點(diǎn)(ReactEmpty)

  • 我們平時(shí)寫 React 代碼的時(shí)候,經(jīng)常會(huì)寫三目表達(dá)式 {this.state.xxx ? <App/> : false}
  • 用來進(jìn)行條件渲染,只知道為 false 就不會(huì)渲染,到底是怎么一回事?
  • 其實(shí),遇到字面量 null, false, true, undefined 在 React 中均會(huì)被創(chuàng)建一個(gè)空節(jié)點(diǎn)
  • 在渲染過程中,如果遇到空節(jié)點(diǎn),那么它將什么都不會(huì)做
    import ReactDOM from 'react-dom/client'const root = ReactDOM.createRoot(document.getElementById('root'));
    // root.render(flase); // 創(chuàng)建空節(jié)點(diǎn) // root.render(true);
    // 創(chuàng)建空節(jié)點(diǎn) root.render(null)
    root.render(undefined) // 創(chuàng)建空節(jié)點(diǎn)
    

5. 數(shù)組節(jié)點(diǎn)(ReactArrayNode)

  • 不是渲染數(shù)組本身,當(dāng)React遇到數(shù)組時(shí),會(huì)創(chuàng)建數(shù)組節(jié)點(diǎn),但是不會(huì)直接進(jìn)行渲染
  • 而是將數(shù)組里的每一項(xiàng)按出來,根據(jù)不同節(jié)點(diǎn)類型去做相應(yīng)的事情
  • 所以,數(shù)組里的每一項(xiàng)只能是這里提到的五個(gè)節(jié)點(diǎn)類型

渲染過程

  • 通過 document.createElement 創(chuàng)建的元素就是真實(shí)的dom
  • React 的工作是通過初始元素或可以生成虛擬節(jié)點(diǎn)的東西生成虛擬節(jié)點(diǎn)然后針對(duì)不同的節(jié)點(diǎn)類型去做不同的事情最終生成真實(shí)dom掛載到頁面上
  • 渲染原理
    • 初始元素和可以生成虛擬節(jié)點(diǎn)的東西
    • 虛擬節(jié)點(diǎn):根據(jù)不同的節(jié)點(diǎn)去做不同的事情
    • 掛載到界面(UI)

首次渲染階段

  • React 會(huì)根據(jù)初始元素先生成虛擬節(jié)點(diǎn),然后做了一系列操作后最終渲染成真實(shí)的UI

  • 根據(jù)不同的虛擬節(jié)點(diǎn)來看它到底做了些什么處理?

  • 1 )初始元素-dom節(jié)點(diǎn)

    • 對(duì)于初始元素的 type 屬性為字符串時(shí),React會(huì)通過 document.createElement 來創(chuàng)建真實(shí)DOM
    • 因?yàn)?#xff0c;初始元素的 type 為字符串,所以直接會(huì)根據(jù) type 屬性創(chuàng)建不同的真實(shí)DOM
    • 創(chuàng)建完真實(shí)DOM后立即設(shè)置該真實(shí)dom的所有屬性,比如,直接在jsx中可以直接書寫的 className, style 等都會(huì)作用到真實(shí)dom上
      // jsx 語法: React初始元素
      const B = <div class='wrapper' style={{color: 'red'}}><p className='text'>123</p>
      </div>
      
    • 當(dāng)然 html 結(jié)構(gòu)肯定不止一層,所以,在設(shè)置完屬性后React會(huì)根據(jù)children屬性進(jìn)行遞歸遍歷
    • 根據(jù)不同的 節(jié)點(diǎn)類型 去做不同的事情,同樣的,如果 children 是初始元素,創(chuàng)建真實(shí)dom、設(shè)置屬性
    • 然后檢查是否有子元素,重復(fù)次步驟,移植到最后一個(gè)元素位置,遇到其他節(jié)點(diǎn)類型會(huì)做以下事情
  • 2 )初始元素-組件節(jié)點(diǎn)

    • 如果初始元素的 type 屬性是一個(gè) class 類 或 function 函數(shù)時(shí)
    • 那么會(huì)創(chuàng)建一個(gè)組件節(jié)點(diǎn),所以,針對(duì)類或函數(shù)組件, 它的處理是不同的
    • 函數(shù)組件
      • 對(duì)于函數(shù)組件會(huì)直接調(diào)用函數(shù),將函數(shù)的返回值進(jìn)行遞歸處理
      • 看看是什么節(jié)點(diǎn)類型,然后去做對(duì)應(yīng)的事情,所以一定要返回能生成虛擬節(jié)點(diǎn)的東西
      • 最終生成一棵vDOM樹
    • 類組件
      • 對(duì)于類組件而言,會(huì)相對(duì)麻煩一些
        • a. 首先創(chuàng)建類的實(shí)例(調(diào)用constructor)
        • b. 調(diào)用生命周期方法 static getDerivedStateFromProps
        • c. 調(diào)用生命周期方法 render, 根據(jù)返回值遞歸處理,跟函數(shù)組件處理返回值一樣,最終生成一棵 vDom樹
        • d. 將該組件的生命周期方法 componentDidMount 加入到執(zhí)行隊(duì)列中等待真實(shí)dom掛載到頁面后執(zhí)行
        • 注意
          • 前面說了 render 是一個(gè)遞歸處理,所以如果一個(gè)組件存在 父子關(guān)系的時(shí)候
          • 那么肯定要等子組件渲染完
        • 父組件才能走出 render, 所以,子組件的 componentDidMount 一定是比父組件
        • 先入隊(duì)列的,肯定先運(yùn)行
  • 3 )文本節(jié)點(diǎn)

    • 針對(duì)文本節(jié)點(diǎn),會(huì)直接通過 document.createTextNode 創(chuàng)建真實(shí)的文本節(jié)點(diǎn)
  • 4 )空節(jié)點(diǎn)

    • 如果生成的是 空節(jié)點(diǎn),那么它將什么都不會(huì)做
  • 5 )數(shù)組節(jié)點(diǎn)

    • 就像前面提到的一樣,React不會(huì)直接渲染數(shù)組,而是將里面的每一項(xiàng)拿出來遍歷
    • 根據(jù)不同的節(jié)點(diǎn)類型去做不同的事,直到遞歸處理完數(shù)組里的每一項(xiàng) (這里流一個(gè)問題,為何數(shù)組里要寫 key)
  • 注意,嵌套組件渲染時(shí)的大致執(zhí)行順序

    • 先執(zhí)行父組件的 constructor, getDerivedStateFromProps, render
    • 再執(zhí)行子組件的 constructor, getDerivedStateFromProps, render, componentDidMount
    • 最后執(zhí)行父組件的 componentDidMount

更新與卸載

  • 掛載完成后組件進(jìn)入活躍狀態(tài),等待數(shù)據(jù)的更新進(jìn)行重新渲染
  • 那么到底有幾種場(chǎng)景會(huì)觸發(fā)更新?整個(gè)過程又是怎么樣的,有哪些需要注意的地方?

組件更新(setState)

  • 最常見的,我們經(jīng)常用 setState 來重新設(shè)置組件的狀態(tài)進(jìn)行重新渲染
  • 使用setState只會(huì)更新調(diào)用此方法的類。不會(huì)涉及到兄弟節(jié)點(diǎn)以及父級(jí)節(jié)點(diǎn)
  • 影響范圍僅僅是自己的子節(jié)點(diǎn),步驟如下:
    • 1 ) 運(yùn)行當(dāng)前類組件的生命周期靜態(tài)方法static getDerivedStateFromProps,根據(jù)返回值合并當(dāng)前組件的狀態(tài)
    • 2 ) 運(yùn)行當(dāng)前類組件的生命周期方法shouldComponentUpdate,如果該方法返回的false,直接終止更新流程
    • 3 ) 運(yùn)行當(dāng)前類組件的生命周期方法render,得到一個(gè)新的vDom樹,進(jìn)入新舊兩棵樹的對(duì)比更新
    • 4 ) 將當(dāng)前類組件的生命周期方法 getSnapshotBeforeUpdate 加入執(zhí)行隊(duì)列,等待將來執(zhí)行
    • 5 ) 將當(dāng)前類組件的生命周期方法 componentDidUpdate 加入執(zhí)行隊(duì)列,等待將來執(zhí)行
    • 6 ) 重新生成vDom樹
    • 7 ) 執(zhí)行隊(duì)列,此隊(duì)列存放的是更新過程涉及到原本存在的類組件的 生命周期 方法 getSnapshotBeforeUpdate
    • 8 ) 根據(jù)vDom樹更新真實(shí)DOM
    • 9 ) 執(zhí)行隊(duì)列,此隊(duì)列存放的是更新過程涉及到原本存在的類組件的 生命周期 方法 componentDidUpdate
    • 10 ) 執(zhí)行隊(duì)列,此隊(duì)列存放的是更新過程中所有卸載的類組件的 生命周期方法 compoentWillUnmount

根節(jié)點(diǎn)更新(ReactDOM.createRoot().render)

  • 在ReactDOM的新版本中,已經(jīng)不是直接使用 ReactDOM.render 進(jìn)行更新了
  • 而是通過 createRoot (要控制的DOM區(qū)域)的返回值來調(diào)用 render
    import React from 'react';
    import ReactDOM from 'react-dom/client';
    import'./index.css';
    import App from'./App';const root = ReactDOM.createRoot(document.getElementById('root');
    root.render(<App/>
    );
    

對(duì)比更新過程(diff)

  • 知道了兩個(gè)更新的場(chǎng)景以及會(huì)運(yùn)行哪些生命周期方法后,我們來看一下具體的過程到底是怎么樣的。
  • 所謂對(duì)比更新就是將新vDom樹跟之前首次渲染過程中保存的老vDom樹對(duì)比發(fā)現(xiàn)差異然后去做一系列操作的過程。
  • 那么問題來了,如果我們?cè)谝粋€(gè)類組件中重新渲染了,React怎么知道在產(chǎn)生的新樹中它的層級(jí)呢?
  • 難道是給vDom樹全部掛上一個(gè)不同的標(biāo)識(shí)來遍歷尋找更新的哪個(gè)組件嗎?
  • 當(dāng)然不是,我們都知道React的diff算法將之前的復(fù)雜度0(n^3)降為了0(n)
  • 它做了以下幾個(gè)假設(shè):
    • 1.假設(shè)此次更新的節(jié)點(diǎn)層級(jí)不會(huì)發(fā)生移動(dòng)(直接找到舊樹中的位置進(jìn)行對(duì)比)
    • 2.兄弟節(jié)點(diǎn)之間通過key進(jìn)行唯一標(biāo)識(shí)
    • 3.如果新舊的節(jié)點(diǎn)類型不相同,那么它認(rèn)為就是一個(gè)新的結(jié)構(gòu)
      • 比如之前是初始元素div現(xiàn)在變成了初始元素 span那么它會(huì)認(rèn)為整個(gè)結(jié)構(gòu)全部變了,
      • 無論嵌套了多深也會(huì)全部丟棄重新創(chuàng)建

key的作用

  • 如果列表里面有初始元素,并且沒有給初始元素添加 key那么它會(huì)警告

    • Warning: Each child in a list should have a unique “key” prop. 。
  • 那么 key值到底是干嘛用的呢?

    • 其實(shí)key的作用非常簡單,僅僅是為了通過舊節(jié)點(diǎn)
    • 尋找對(duì)應(yīng)的新節(jié)點(diǎn)進(jìn)行對(duì)比提高節(jié)點(diǎn)的復(fù)用率
  • 現(xiàn)在來舉個(gè)例子,假如現(xiàn)在有五個(gè)兄弟節(jié)點(diǎn)更新后變成了四個(gè)節(jié)點(diǎn)

  • 未添加key

  • 添加了key

找到對(duì)比目標(biāo)-節(jié)點(diǎn)類型一致

  • 經(jīng)過假設(shè)和一系列的操作找到了需要對(duì)比的目標(biāo)
  • 如果發(fā)現(xiàn)節(jié)點(diǎn)類型一致,那么它會(huì)根據(jù)不同的節(jié)點(diǎn)類型做不同的事情
  1. 初始元素-DOM節(jié)點(diǎn)
  • 如果是DOM節(jié)點(diǎn),React會(huì)直接重用之前的真實(shí)DOM
  • 將這次變化的屬性記錄下來,等待將來完成更新
  • 然后遍歷其子節(jié)點(diǎn)進(jìn)行遞歸對(duì)比更新
  1. 初始元素-組件節(jié)點(diǎn)
  • 函數(shù)組件
    • 如果是函數(shù)組件,React僅僅是重新調(diào)用函數(shù)拿到新的vDom樹,然后遞歸進(jìn)行對(duì)比更新
  • 類組件
    • 針對(duì)類組件,React也會(huì)重用之前的實(shí)例對(duì)象。后續(xù)步驟如下:
    • 1.運(yùn)行生命周期靜態(tài)方法static getDerivedStateFromProps。將返回值合并當(dāng)前狀態(tài)
    • 2.運(yùn)行生命周期方法shouldComponentUpdate,如果該方法返回false,終止當(dāng)前流程
    • 3.運(yùn)行生命周期方法render,得到新的vDom樹,進(jìn)行新舊兩棵樹的遞歸對(duì)比更新
    • 4.將生命周期方法getSnapshotBeforeUpdate加入到隊(duì)列等待執(zhí)行
    • 5.將生命周期方法componentDidUpdate加入到隊(duì)列等待執(zhí)行

3.文本節(jié)點(diǎn)

  • 對(duì)于文本節(jié)點(diǎn),同樣的React也會(huì)重用之前的真實(shí)文本節(jié)點(diǎn)。
  • 將新的文本記錄下來,等待將來統(tǒng)一更新(設(shè)置nodeValue)

4.空節(jié)點(diǎn)

  • 如果節(jié)點(diǎn)的類型都是空節(jié)點(diǎn),那么React啥都不會(huì)做

5.數(shù)組節(jié)點(diǎn)

  • 首次掛載提到的,數(shù)組節(jié)點(diǎn)不會(huì)直接渲染
  • 在更新階段也一樣,遍歷每一項(xiàng),進(jìn)行對(duì)比更新,然后去做不同的事

找到對(duì)比目標(biāo)-節(jié)點(diǎn)類型不一致

  • 如果找到了對(duì)比目標(biāo),但是發(fā)現(xiàn)節(jié)點(diǎn)類型不一致了,這時(shí)候類型變了,那么你的子節(jié)點(diǎn)肯定也都不一樣了
  • 就算一萬個(gè)子節(jié)點(diǎn),并且他們都是沒有變化的,只有最外層的父節(jié)點(diǎn)的節(jié)點(diǎn)類型變了
  • 照樣會(huì)全部進(jìn)行卸載重新創(chuàng)建,與其去一個(gè)個(gè)遞歸查看子節(jié)點(diǎn),不如直接全部卸載重新創(chuàng)建
    import'./App.css';
    import React from 'react';function Count(props) {console.log('Count')return <h1>{props. count}</h1>
    }class App extends React. Component {constructor() {super()this.state={arr:[1,2,3]}this.update =this.update.bind(this)}update() {this.setState({arr: [1,2,3,4]})}render() {console.log('父親render執(zhí)行')return (<div><button onClick={this.update}>點(diǎn)我更新</button>{ this.state.arr.map((count) => <Count key={count} count={count} />) }</div>)}
    }
    export default App;
    
    • 這個(gè)例子,初始化的時(shí)候,Count組件被初始化3次
    • 而點(diǎn)擊更新的時(shí)候,Count組件更新了4次
    • 這是因?yàn)樗呛瘮?shù)式組件,更新時(shí),僅僅是重新調(diào)用函數(shù),拿到新的vDOM樹
    • 在react內(nèi)部加了key,可以復(fù)用的是底層的vDom的樹,而非這個(gè)函數(shù)式組件
    • 函數(shù)式組件,每次渲染,都會(huì)重新執(zhí)行這個(gè)函數(shù),這里要分清兩者的區(qū)別

未找到對(duì)比目標(biāo)

  • 如果未找到對(duì)比的目標(biāo),跟 節(jié)點(diǎn)類型 不一致的做法類似,
  • 那么對(duì)于多出的節(jié)點(diǎn)進(jìn)行掛載流程,對(duì)于舊節(jié)點(diǎn)進(jìn)行卸載直接棄用
  • 如果其包含子節(jié)點(diǎn)進(jìn)行遞歸卸載,對(duì)于初始類組件節(jié)點(diǎn)會(huì)多一個(gè)步驟,那就是運(yùn)行生命周期方法componentWillUnmount。
  • 注意:
    • 盡量保持結(jié)構(gòu)的穩(wěn)定性,如果未添加key的情況下
    • 兄弟節(jié)點(diǎn)更新位置前后錯(cuò)位一個(gè)那么后續(xù)全部的比較都會(huì)錯(cuò)位導(dǎo)致找不到對(duì)比目標(biāo)從而進(jìn)行卸載新建流程,對(duì)性能大打折扣

總結(jié)

  • 對(duì)于首次掛載階段
    • 需要了解React的渲染流程
    • 通過書寫的初始元素和一些其他可以生成虛擬節(jié)點(diǎn)的東西來生成虛擬節(jié)點(diǎn)
    • 然后針對(duì)不同的節(jié)點(diǎn)類型去做不同的事情,最終將真實(shí)DOM掛載到頁面上
    • 然后執(zhí)行渲染期間加入到隊(duì)列的一些生命周期,然后組件進(jìn)入到活躍狀態(tài)
  • 對(duì)于更新卸載階段
    • 需要注意的是有幾個(gè)更新的場(chǎng)景,以及key的作用到底是什么,有或沒有會(huì)產(chǎn)生多大的影響
    • 還有一些小細(xì)節(jié),比如條件渲染時(shí),不要去破壞結(jié)構(gòu),盡量使用空節(jié)點(diǎn)來保持前后結(jié)構(gòu)順序的統(tǒng)一
    • 重點(diǎn)是新舊兩棵樹的對(duì)比更新流程
    • 找到目標(biāo),節(jié)點(diǎn)類型一致時(shí)針對(duì)不同的節(jié)點(diǎn)類型會(huì)做哪些事,類型不一致時(shí)會(huì)去卸載整個(gè)舊節(jié)點(diǎn)
    • 無論有多少子節(jié)點(diǎn),都會(huì)全部遞歸進(jìn)行卸載
http://www.risenshineclean.com/news/6703.html

相關(guān)文章:

  • 好的網(wǎng)站建設(shè)案例河北網(wǎng)站建設(shè)制作
  • 專門做面包和蛋糕的網(wǎng)站建立一個(gè)網(wǎng)站需要多少錢?
  • 可以做mc圖片的網(wǎng)站外鏈推廣
  • 深圳市網(wǎng)站建設(shè)公網(wǎng)絡(luò)搭建是干什么的
  • 設(shè)計(jì)電子商務(wù)網(wǎng)站主頁鄭州seo教程
  • 江西建筑培訓(xùn)網(wǎng)seo就業(yè)哪家好
  • 做公司網(wǎng)站需要注意什么護(hù)膚品營銷策劃方案
  • 印刷網(wǎng)站建設(shè)建立網(wǎng)站怎么搞
  • 杭州品牌網(wǎng)站制作培訓(xùn)班
  • 寵物店做網(wǎng)站的論文深圳網(wǎng)絡(luò)推廣
  • 專業(yè)網(wǎng)站推廣引流外鏈圖片
  • 英文網(wǎng)站模板改成中文成都百度快照優(yōu)化排名
  • 免費(fèi)域名申請(qǐng)哪個(gè)網(wǎng)站好百度營銷客戶端
  • 自己創(chuàng)業(yè)做原公司一樣的網(wǎng)站武漢網(wǎng)站排名提升
  • 找設(shè)計(jì)公司上哪個(gè)網(wǎng)站網(wǎng)絡(luò)營銷課程主要講什么內(nèi)容
  • 做電商要有網(wǎng)站嗎seo關(guān)鍵詞排名優(yōu)化報(bào)價(jià)
  • 做網(wǎng)站找哪家怎么創(chuàng)建網(wǎng)站?
  • 動(dòng)態(tài)網(wǎng)站做優(yōu)化搭建網(wǎng)站需要什么技術(shù)
  • 建設(shè)銀行上海分行網(wǎng)站網(wǎng)站seo快速排名優(yōu)化的軟件
  • 儀征網(wǎng)站建設(shè)友鏈查詢站長工具
  • 手機(jī)開網(wǎng)店用什么軟件seo優(yōu)化排名
  • 婚紗攝影的網(wǎng)站怎么做推廣網(wǎng)站哪個(gè)好
  • 做網(wǎng)站怎樣辦營業(yè)執(zhí)照搜狗網(wǎng)頁版入口
  • 用vs做網(wǎng)站如何連接數(shù)據(jù)庫最新國內(nèi)你新聞
  • 手機(jī)版網(wǎng)站建設(shè)百度競(jìng)價(jià)包年推廣是怎么回事
  • 財(cái)政部網(wǎng)站官網(wǎng) PPP項(xiàng)目建設(shè)關(guān)鍵詞排名查詢網(wǎng)站
  • 網(wǎng)站建設(shè)對(duì)產(chǎn)品推銷作用大嗎百度云搜索引擎入口盤多多
  • 黑龍江建設(shè)廳網(wǎng)站官網(wǎng)做網(wǎng)站優(yōu)化哪家公司好
  • 給網(wǎng)站整一個(gè)客服 怎么做鳳凰網(wǎng)全國疫情實(shí)時(shí)動(dòng)態(tài)
  • 上海網(wǎng)站建設(shè)設(shè)計(jì)公司排名無錫百度推廣開戶