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

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

合作社網(wǎng)站模板search搜索引擎

合作社網(wǎng)站模板,search搜索引擎,企業(yè)郵箱263,自己做應(yīng)用的網(wǎng)站一. 發(fā)生更新的時機以及順序## image.png props/state改變render函數(shù)重新執(zhí)行產(chǎn)生新的VDOM樹新舊DOM樹進(jìn)行diff計算出差異進(jìn)行更新更新到真實的DOM 二. React更新流程## React將最好的O(n^3)的tree比較算法優(yōu)化為O(n)。 同層節(jié)點之間相互比較,不跨節(jié)點。不同類型的節(jié)…

一. 發(fā)生更新的時機以及順序##

image.png
  1. props/state改變
  2. render函數(shù)重新執(zhí)行
  3. 產(chǎn)生新的VDOM樹
  4. 新舊DOM樹進(jìn)行diff
  5. 計算出差異進(jìn)行更新
  6. 更新到真實的DOM

二. React更新流程##

React將最好的O(n^3)的tree比較算法優(yōu)化為O(n)。

  • 同層節(jié)點之間相互比較,不跨節(jié)點。
  • 不同類型的節(jié)點,產(chǎn)生不同的樹結(jié)構(gòu):如果該節(jié)點不同,會將舊tree中該節(jié)點的子樹全部刪掉。直接生成新的子樹,掛載到DOM中。
  • 開發(fā)中,可以通過key來指定哪些節(jié)點在不同的渲染下保持穩(wěn)定。

三. 不同情況##

情況一:對比不同類型的元素
當(dāng)節(jié)點為不同的元素,React會拆卸原有的樹,并且建立起新的樹。

  • 當(dāng)一個元素改變,會觸發(fā)一個完整的重建流程。
  • 當(dāng)卸載一棵樹時,對應(yīng)的DOM節(jié)點也會被銷毀,組件實例將執(zhí)行componentWillUnmount()方法。
  • 當(dāng)建立一棵新樹時,對應(yīng)得DOM節(jié)點會被創(chuàng)建以及插入到DOM中,組件實例將執(zhí)行componentWillMount()方法,緊接著componentDidMount()方法。
  • 子樹銷毀,元素不會復(fù)用。####

情況二:對比同一類型的元素

  • 當(dāng)對比兩個相同類型的React元素時,React會保留DOM節(jié)點,僅比對及更新有改變的屬性, 比如下面例子:
image.png
  • React知道只需要修改DOM元素上的className屬性。

image.png

-當(dāng) 更新style屬性時,React僅更新有所改變的屬性,沒有變化的屬性不會變。

  • 如果是同類型的組件元素:組件會保持不變,React會更新該組件的props,并且調(diào)用componentWillReceiveProps()和componentWillUpdate()方法;
  • 下一步,調(diào)用render()方法,diff算法將在之前的結(jié)果以及新的結(jié)果中進(jìn)行遞歸。

情況三:對子節(jié)點進(jìn)行遞歸

image.png
  • 默認(rèn)條件下,當(dāng)遞歸DOM節(jié)點的子元素時,React會同時遍歷兩個子元素的列表;當(dāng)產(chǎn)生差異時,生成一個mutation。
  • 如上圖,前兩個比較相同,不會有mutation。
  • 最后一個比較,產(chǎn)生一個mutation,將其插入到新的DOM樹中即可。
  • 當(dāng)然這是理想情況
image.png

如果我們在中間插入一條數(shù)據(jù):

  • React會對每一個子元素產(chǎn)生一個mutation,而不是保持其不變。
  • 這種方式會有一定的性能問題。

所以這時需要key來優(yōu)化###

四. key優(yōu)化##

  1. 在尾部添加數(shù)據(jù)
  • 有無key意義并不大。
  1. 在前面插入數(shù)據(jù)
  • 這種情況,在沒有key的情況下,所有l(wèi)i都需要進(jìn)行修改。
  • 當(dāng)子元素?fù)碛衚ey時,React使用key來匹配原有樹上的子元素以及最新樹上的子元素:這種情況下:原有的元素只是發(fā)生了位移。
  render() {return (<div><h2>電影列表</h2><ul>{this.state.movies.map((item,index) => {return <li key={item}>{item}</li>})}</ul><button onClick={e => this.insertMovie()}>添加電影</button></div>)}
  1. key的注意事項:
  • key應(yīng)該是唯一的。
  • key不要使用隨機數(shù)(隨機數(shù)在下一次render時,會重新生成一個數(shù)字)。
  • 使用index作為key,對性能是沒有優(yōu)化的,id比較合適。

五. 組件嵌套的render調(diào)用##

import React, { Component } from 'react'// Header
function Header() {console.log("Header被調(diào)用");return <h2>我是Header組件</h2>
}// Banner
class Banner extends Component {render() {console.log('Banner的render函數(shù)被調(diào)用');return <h3>我是bannner組件</h3>}
}function ProductList() {console.log("ProductList被調(diào)用");return (<ul><li>商品列表1</li><li>商品列表2</li><li>商品列表3</li><li>商品列表4</li><li>商品列表5</li></ul>)
}
// Main
class Main extends Component {render() {console.log('Main render函數(shù)被調(diào)用');return (<div><Banner /><ProductList /></div >)}
}
// Footer
function Footer() {console.log("Footer被調(diào)用");return <h2>我是Footer組件</h2>
}export default class App extends Component {constructor(props) {super(props);this.state = {counter: 0,}}render() {console.log('App render函數(shù)被調(diào)用');return (<div><h2>當(dāng)前計數(shù):{this.state.counter}</h2><button onClick={e=>this.increment()}>+1</button><Header /><Main /><Footer /></div>)}increment(){this.setState({counter: this.state.counter + 1})}
}
  • 調(diào)用一個無關(guān)的函數(shù),界面改變時,按理來說不應(yīng)該讓別的沒有改變的東西重新render。
  • 這個例子中我們在前面插入了一個<h2>和<button>標(biāo)簽,現(xiàn)在點擊按鈕時全局都會重新渲染。
  • 現(xiàn)在對其進(jìn)行優(yōu)化

六. 組件嵌套的render調(diào)用的優(yōu)化##

  • 調(diào)用完setState后,不想render時阻斷其渲染。
  • 使用shouldComponentUpdate() {}這個生命函數(shù),默認(rèn)情況下其返回true,也就是重新渲染;手動設(shè)置為false后,將不會重新渲染,但不影響初始化的渲染。
  • 我們的目的是:想要阻斷時阻斷(事件發(fā)生后與界面沒有依賴),不想阻斷時渲染,如下代碼。
  shouldComponentUpdate(nextProps, nextState){if(this.state.counter !== nextState.counter){return true;}return false;}

以上為簡單情況,當(dāng)組件變多后,情況將很復(fù)雜,函數(shù)/類組件都需要考慮到###

  • 每個類都設(shè)置該生命周期函數(shù)太麻煩。

  • 我們通過繼承PureComponent而不是Component來進(jìn)行簡化,其會對state和props進(jìn)行比較來決定是否重新render。

  • shouldComponentUpdate在源碼中進(jìn)行更新時,決定是否需要render。

  • 回溯到源碼ReactFiberClassComponent中時,有如下方法:

function checkShouldComponentUpdate(workInProgress,ctor,oldProps,newProps,oldState,newState,nextContext,
) {const instance = workInProgress.stateNode;
// 判斷有無該生命周期函數(shù)if (typeof instance.shouldComponentUpdate === 'function') {    
startPhaseTimer(workInProgress, 'shouldComponentUpdate');
// -----------------
// 核心代碼const shouldUpdate = instance.shouldComponentUpdate(newProps,newState,nextContext,);stopPhaseTimer();return shouldUpdate;}
// -----------------if (ctor.prototype && ctor.prototype.isPureReactComponent) {return (!shallowEqual(oldProps, newProps) || !shallowEqual(oldState, newState));}return true;
}
  • 該方法最終返回true/false。
  • 這個對應(yīng)React中PureComponent的特點
    image.png
  • 其中isPureReactComponent屬性對應(yīng)上面放出來源代碼中對原型中isPureReactComponent屬性的判斷。
  • 如果有isPureReactComponent屬性,則對oldProps,oldState和newProps,newState進(jìn)行一個淺層比較。
  • 通過淺層比較來判斷是否發(fā)生了改變。

追溯到shallowEqual方法源碼中

import is from './objectIs';const hasOwnProperty = Object.prototype.hasOwnProperty;/*** Performs equality by iterating through keys on an object and returning false* when any key has values which are not strictly equal between the arguments.* Returns true when the values of all keys are strictly equal.*/
function shallowEqual(objA: mixed, objB: mixed): boolean {if (is(objA, objB)) {return true;}if (typeof objA !== 'object' ||objA === null ||typeof objB !== 'object' ||objB === null) {return false;}const keysA = Object.keys(objA);const keysB = Object.keys(objB);if (keysA.length !== keysB.length) {return false;}// Test for A's keys different from B.for (let i = 0; i < keysA.length; i++) {if (!hasOwnProperty.call(objB, keysA[i]) ||!is(objA[keysA[i]], objB[keysA[i]])) {return false;}}return true;
}export default shallowEqual;
  • 先判斷兩個對象,相同則true,返回后取反,表示不需要更新。
  • 接著分別判斷兩個對象,不是對象或者為null時返回false,強制刷新
  • 然后將兩個對象中的keys取出來,若長度不想等則返回false,若相等,則對其中屬性進(jìn)行比較,不相等則返回false進(jìn)行刷新。

這就回到我們案例中,只有App,Header,Footer的render被調(diào)用。

  • PureComponent對props和state進(jìn)行shallowEqual 。
  • Main,Banner,ProductList沒有依賴任何props/state,所以沒有重新渲染。
  • 開發(fā)中只需要shallowEqual深層比較非常浪費性能。
  • PureComponent可以解決類組件的render調(diào)用,但解決不了函數(shù)式組件

七. memo的使用,優(yōu)化函數(shù)式組件##

memo為高階組件。

const MemoHeader = memo(function Header() {console.log("Header被調(diào)用");return <h2>我是Header組件</h2>
})
image.png
  • 我們將原來的函數(shù)組件傳入memo函數(shù)中,生成一個新的組件類型。
  • 將Footer也進(jìn)行轉(zhuǎn)換,這樣只有App重新渲染了,
  • 但我們沒有更改ProductList,其也沒有重新渲染,原因是在Main中,重新渲染已經(jīng)被阻止了
  • 為了以防萬一,也可以用memo優(yōu)化。

理論上:建議所有類組件都用PureComponent,所有函數(shù)組件都包裹memo



喜歡的朋友記得點贊、收藏、關(guān)注哦!!!

http://www.risenshineclean.com/news/8949.html

相關(guān)文章:

  • 好的網(wǎng)頁網(wǎng)站設(shè)計搜索引擎推廣方案
  • 新手搭建論壇己做網(wǎng)站網(wǎng)絡(luò)銷售怎么做才能做好
  • 百度框架戶開戶渠道seo建設(shè)招商
  • 門戶網(wǎng)站信息發(fā)布管理辦法童程童美少兒編程怎樣收費
  • 揭陽網(wǎng)站制作建設(shè)免費發(fā)布信息的網(wǎng)站平臺
  • 微信二維碼網(wǎng)站建設(shè)白帽seo是什么
  • 學(xué)校官方網(wǎng)站專業(yè)做網(wǎng)站
  • 云南網(wǎng)站制作案例百度云盤資源共享鏈接群組鏈接
  • 武漢工程信息網(wǎng)seo入門教程視頻
  • 網(wǎng)絡(luò)公司的網(wǎng)頁設(shè)計圖片優(yōu)化是什么意思
  • 大良商城網(wǎng)站建設(shè)2023疫情最新消息今天
  • 個人站長做導(dǎo)航網(wǎng)站百度手機瀏覽器
  • 網(wǎng)站后臺后綴名惠州seo代理商
  • 行業(yè)獵頭網(wǎng)seo中文
  • 國內(nèi)網(wǎng)站賞析社群營銷的具體方法
  • dw做網(wǎng)站教程汕頭搜索引擎優(yōu)化服務(wù)
  • 學(xué)習(xí)做網(wǎng)站soso搜搜
  • wordpress 扁平化響應(yīng)式主題谷歌seo課程
  • 建設(shè)外賣網(wǎng)站規(guī)劃書網(wǎng)站頁面布局和樣式設(shè)計
  • 青島企業(yè)建設(shè)網(wǎng)站企業(yè)電商運營工資大概多少
  • 類似17做網(wǎng)店的網(wǎng)站杭州百度seo
  • 咋么做網(wǎng)站谷歌廣告推廣怎么做
  • 青島市網(wǎng)站建設(shè)公司百度官網(wǎng)認(rèn)證申請
  • 佛山微網(wǎng)站建設(shè) 天博廣東省疫情最新
  • 宜昌視頻網(wǎng)站建設(shè)優(yōu)化大師最新版下載
  • 做網(wǎng)站一個月能掙多少媒體:多地新增感染趨勢回落
  • 畢業(yè)設(shè)計題目河南靠譜seo電話
  • 一個人搞得定網(wǎng)站建設(shè)網(wǎng)絡(luò)seo優(yōu)化公司
  • 如何在網(wǎng)站申請做co谷歌搜索引擎入口2021
  • 網(wǎng)站建設(shè)技術(shù)指標(biāo)營銷型網(wǎng)站建設(shè)步驟