成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

React 生命周期

Dean / 1107人閱讀

摘要:同步渲染的痛點(diǎn)當(dāng)應(yīng)用的組件樹特別龐大時(shí),由于是單線程的,重新渲染一旦開始,中間不會(huì)停,如果這時(shí)候用戶去操作,比如輸入,點(diǎn)擊按鈕,此時(shí)頁面是沒有響應(yīng)的。

React生命周期 基礎(chǔ)生命周期鉤子

constructor

如果你不初始化狀態(tài),也不綁定方法,那么你就不需要為React組件實(shí)現(xiàn)構(gòu)造函數(shù)。在這里初始化狀態(tài)可以直接對(duì)this.state賦值,在這里使用props時(shí),應(yīng)當(dāng)通過this.props使用;如果組件內(nèi)定義的方法不是采用箭頭函數(shù)默認(rèn)綁定到組件實(shí)例上時(shí),調(diào)用時(shí)應(yīng)該用bind手動(dòng)綁定。

componentWillMount(將要廢棄)

在react17版本前有效的生命周期鉤子,不能與新版鉤子混用(componentWillRecevieProps、componentWillUpdate也是如此);
有一種常見的誤區(qū)是在componentWillMount中請(qǐng)求數(shù)據(jù)可以避免第一次empty render,但實(shí)際中render在componentWillMount后立即執(zhí)行,如果componentWillMount拉取的數(shù)據(jù)不能立即得到,那么二次渲染依然無法避免,這種情況下推薦在componentDidMount中請(qǐng)求數(shù)據(jù)。
所以總的來說沒啥用處。

render

render()方法是類組件唯一必須的方法,在該鉤子內(nèi),將React JSX 渲染為DOM節(jié)點(diǎn)。
render()函數(shù)應(yīng)該是純的,意味著不應(yīng)該改變組件的狀態(tài),其每次調(diào)用都應(yīng)返回相同的結(jié)果,同時(shí)它不會(huì)直接和瀏覽器交互

componentDidMount

在該鉤子內(nèi),render生成的DOM節(jié)點(diǎn)掛載到DOM樹中,在這里你可以通過ref取到DOM節(jié)點(diǎn),有些需求下,可能需要DOM節(jié)點(diǎn)掛載后才能取到相應(yīng)的屬性,例如DOM節(jié)點(diǎn)的尺寸等,你可以立即調(diào)用setState()。它將會(huì)觸發(fā)一次額外的渲染,但是它將在瀏覽器刷新屏幕之前發(fā)生。這保證了在此情況下即使render()將會(huì)調(diào)用兩次,用戶也不會(huì)看到中間狀態(tài)。

componentWillUnmount

componentWillUnmount()緊挨著在組件被卸載和銷毀之前調(diào)用??梢栽谠摲椒ɡ锾幚砣魏伪匾那謇砉ぷ?,例如解綁定時(shí)器,取消網(wǎng)絡(luò)請(qǐng)求,清理任何在componentDidMount環(huán)節(jié)創(chuàng)建的訂閱。

稍微進(jìn)階的生命周期鉤子

上述介紹的基本生命周期鉤子是上圖的左半部分,走完了一次初始渲染的流程,但React組件嵌套復(fù)用,當(dāng)父組件更新或者組件自身狀態(tài)更新觸發(fā)子組件重新渲染時(shí),合理的使用上圖右半部分的生命周期鉤子可以有效提升性能。

componentWillReceiveProps(nextProps)(將要廢棄)

componentWillReceiveProps()在裝載了的組件接收到新屬性前調(diào)用??赡墚?dāng)接收到新屬性后,通過if比較新舊Props不同,想要通過this.setState()來更新組件的狀態(tài)。

shouldComponentUpdate(nextProps, nextState)

當(dāng)接收到新屬性或狀態(tài)時(shí),shouldComponentUpdate() 在渲染前被調(diào)用。默認(rèn)為true。該方法在初始化渲染或當(dāng)使用forceUpdate()時(shí)并不會(huì)被調(diào)用。
適用場(chǎng)景是:你想在某些狀態(tài)或?qū)傩宰兓瘯r(shí),通過this.props和nextProps以及this.state 和 nextState比較,來判斷是否需要重新渲染該組件,return fasle 不渲染,默認(rèn)為true。不能setState。
有內(nèi)建的React.PureComponent代替手寫shouldComponentUpdate()。PureComponent 對(duì)屬性和狀態(tài)執(zhí)行淺比較,因而降低你略過必要更新的機(jī)會(huì)。
但如果你需要更精細(xì)的控制,那就自定義shouldComponentUpdate吧。
但是當(dāng)你的state或props是嵌套很深的引用類型時(shí),容易由于淺比較而出錯(cuò),而React文檔說我們不推薦做深相等檢測(cè),或使用JSON.stringify()在shouldComponentUpdate()中,這是非常無效率的會(huì)傷害性能。所以你最好設(shè)計(jì)好自己的數(shù)據(jù)結(jié)構(gòu),不要讓數(shù)據(jù)嵌套太深。

componentWillUpdate(nextProps, nextState)

類似于componentWillMount,在nextProps, nextState生效前最后的一次準(zhǔn)備機(jī)會(huì),可以讀取DOM屬性,為componentDidUpdate作準(zhǔn)備(使用場(chǎng)景少)。不能setState。

componentDidUpdate

組件更新后觸發(fā),類似于componentDidMount的作用,可以在這里操作DOM,發(fā)起請(qǐng)求等。

參考鏈接:
React Lifecycle Methods- how and when to use them
React組件生命周期小結(jié)

React v16.3新出的生命周期鉤子

static getDerivedStateFromProps(nextProps, prevState)

與舊的生命周期圖比較可以看出,getDerivedStateFromProps處于原來的componentWillMountcomponentWillReceiveProps位置,而且this.setState()以及this.forceUpdate()也會(huì)觸發(fā)該鉤子。
該鉤子的主要作用是為了替代componentWillReceiveProps作用。

// Before
class ExampleComponent extends React.Component {
  state = {
    isScrollingDown: false,
  };
  componentWillReceiveProps(nextProps) {
    if (this.props.currentRow !== nextProps.currentRow) {
      this.setState({
        isScrollingDown:
          nextProps.currentRow > this.props.currentRow,
      });
    }
  }
}
// After
class ExampleComponent extends React.Component {
  state = {
    isScrollingDown: false,
    lastRow: null,
  };

  static getDerivedStateFromProps(nextProps, prevState) {
    if (nextProps.currentRow !== prevState.lastRow) {
      return {
        isScrollingDown:
          nextProps.currentRow > prevState.lastRow,
        lastRow: nextProps.currentRow,
      };
    }

    // Return null to indicate no change to state.
    return null;
  }
}

與原有鉤子相比,getDerivedStateFromProps是一個(gè)靜態(tài)方法,無法訪問組件實(shí)例,如此限制了其使用范圍,防止不熟練的開發(fā)者自由發(fā)揮導(dǎo)致各種bug。該鉤子主要作用可以概括為接收props來改變state。

可以發(fā)現(xiàn)在使用getDerivedStateFromProps時(shí),我們?cè)趕tate中多花了一個(gè)變量lastRow來保存prevProps,為什么設(shè)計(jì)鉤子的時(shí)候不在參數(shù)值加入prevProps呢? 官方文檔的解釋是:1.首次渲染也會(huì)觸發(fā)getDerivedStateFromProps,這意味著每次都需要對(duì)prevProps進(jìn)行空置檢測(cè),麻煩;2.不將prevProps傳入是為了節(jié)省內(nèi)存。

getSnapshotBeforeUpdate(prevProps, prevState)

取代componenWillUpdate功能。
getSnapshotBeforeUpdate在最新的渲染輸出提交給DOM前將會(huì)立即調(diào)用。它讓你的組件能在當(dāng)前的值可能要改變前獲得它們。這一生命周期返回的任何值將會(huì) 作為參數(shù)被傳遞給componentDidUpdate()。

class ScrollingList extends React.Component {
  listRef = null;

  getSnapshotBeforeUpdate(prevProps, prevState) {
    // Are we adding new items to the list?
    // Capture the current height of the list so we can adjust scroll later.
    if (prevProps.list.length < this.props.list.length) {
      return this.listRef.scrollHeight;
    }
    return null;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    // If we have a snapshot value, we"ve just added new items.
    // Adjust scroll so these new items don"t push the old ones out of view.
    // (snapshot here is the value returned from getSnapshotBeforeUpdate)
    if (snapshot !== null) {
      this.listRef.scrollTop +=
        this.listRef.scrollHeight - snapshot;
    }
  }

  render() {
    return (
      
{/* ...contents... */}
); } setListRef = ref => { this.listRef = ref; }; }

static getDerivedStateFromError()componentDidCatch()

錯(cuò)誤處理。。。
render phase 里產(chǎn)生異常的時(shí)候, 會(huì)調(diào)用 getDerivedStateFromError;

在 commit phase 里產(chǎn)生異常大的時(shí)候, 會(huì)調(diào)用 componentDidCatch。

componentDidCatch 是不會(huì)在服務(wù)器端渲染的時(shí)候被調(diào)用的 而getDerivedStateFromError 會(huì)

為何用推出新的鉤子,廢棄舊的鉤子?

主要是為了適應(yīng)將要推出的異步渲染,其次是避免之前生命周期鉤子的濫用。

同步渲染與異步渲染

React Fiber 是在 v16 的時(shí)候引入的一個(gè)全新架構(gòu), 旨在解決異步渲染問題,但v16并沒有開啟。
同步渲染的痛點(diǎn):當(dāng)應(yīng)用的組件樹特別龐大時(shí),由于javaScript是單線程的,重新渲染一旦開始,中間不會(huì)停,如果這時(shí)候用戶去操作, 比如輸入, 點(diǎn)擊按鈕, 此時(shí)頁面是沒有響應(yīng)的。 等更新完了, 你之前的那些輸入就會(huì)啪啪啪一下子出來了。函數(shù)調(diào)用棧如圖所示:

因?yàn)镴avaScript單線程的特點(diǎn),每個(gè)同步任務(wù)不能耗時(shí)太長(zhǎng),不然就會(huì)讓程序不會(huì)對(duì)其他輸入作出相應(yīng),React的更新過程就是犯了這個(gè)禁忌,而React Fiber就是要改變現(xiàn)狀。

Fiber 的做法是:分片。
把一個(gè)很耗時(shí)的任務(wù)分成很多小片,每一個(gè)小片的運(yùn)行時(shí)間很短,雖然總時(shí)間依然很長(zhǎng),但是在每個(gè)小片執(zhí)行完之后,都給其他任務(wù)一個(gè)執(zhí)行的機(jī)會(huì),這樣唯一的線程就不會(huì)被獨(dú)占,其他任務(wù)依然有運(yùn)行的機(jī)會(huì)。 而維護(hù)每一個(gè)分片的數(shù)據(jù)結(jié)構(gòu), 就是Fiber。
用一張圖來展示Fiber 的碎片化更新過程

在React Fiber中,一次更新過程會(huì)分成多個(gè)分片完成,所以完全有可能一個(gè)更新任務(wù)還沒有完成,就被另一個(gè)更高優(yōu)先級(jí)的更新過程打斷,這時(shí)候,優(yōu)先級(jí)高的更新任務(wù)會(huì)優(yōu)先處理完,而低優(yōu)先級(jí)更新任務(wù)所做的工作則會(huì)完全作廢,然后等待機(jī)會(huì)重頭再來。

因?yàn)橐粋€(gè)更新過程可能被打斷,所以React Fiber一個(gè)更新過程被分為兩個(gè)階段: render phase and commit phase.(可以從上文的生命周期圖中看到)

因?yàn)榈谝浑A段的過程會(huì)被打斷而且“重頭再來”,就會(huì)造成意想不到的情況。

比如說,一個(gè)低優(yōu)先級(jí)的任務(wù)A正在執(zhí)行,已經(jīng)調(diào)用了某個(gè)組件的componentWillUpdate函數(shù),接下來發(fā)現(xiàn)自己的時(shí)間分片已經(jīng)用完了,于是冒出水面,看看有沒有緊急任務(wù),哎呀,真的有一個(gè)緊急任務(wù)B,接下來React Fiber就會(huì)去執(zhí)行這個(gè)緊急任務(wù)B,任務(wù)A雖然進(jìn)行了一半,但是沒辦法,只能完全放棄,等到任務(wù)B全搞定之后,任務(wù)A重頭來一遍,注意,是重頭來一遍,不是從剛才中段的部分開始,也就是說,componentWillUpdate函數(shù)會(huì)被再調(diào)用一次。

在現(xiàn)有的React中,每個(gè)生命周期函數(shù)在一個(gè)加載或者更新過程中絕對(duì)只會(huì)被調(diào)用一次;在React Fiber中,不再是這樣了,第一階段中的生命周期函數(shù)在一次加載和更新過程中可能會(huì)被多次調(diào)用!。

總而言之就是:
render phase 可以被打斷, 大家不要在此階段做一些有副作用的操作,可以放心在commit phase 里做。

然后就是生命周期的調(diào)整, react 把你有可能在render phase 里做的有副作用的函數(shù)都改成了static 函數(shù), 強(qiáng)迫開發(fā)者做一些純函數(shù)的操作。

全面了解 React 新功能: Suspense 和 Hooks

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/109090.html

相關(guān)文章

  • React專題:生命周期

    摘要:而生命周期鉤子,就是從生到死過程中的關(guān)鍵節(jié)點(diǎn)。異步渲染下的生命周期花了兩年時(shí)間祭出渲染機(jī)制。目前為這幾個(gè)生命周期鉤子提供了別名,分別是將只提供別名,徹底廢棄這三個(gè)大活寶。生命周期鉤子的最佳實(shí)踐是在這里初始化。 本文是『horseshoe·React專題』系列文章之一,后續(xù)會(huì)有更多專題推出來我的 GitHub repo 閱讀完整的專題文章來我的 個(gè)人博客 獲得無與倫比的閱讀體驗(yàn) 生命周期...

    Hanks10100 評(píng)論0 收藏0
  • 捋一捋React生命周期

    摘要:卸載階段組件卸載和銷毀老版生命周期之前的生命周期初始化階段涉及個(gè)鉤子函數(shù)這些方法會(huì)在組件初始化的時(shí)候被調(diào)用,只跟實(shí)例的創(chuàng)建有關(guān)。 前言:React 的版本從 v15 到 v16.3 ,再到v16.4,現(xiàn)在最新的版本是 v16.8了。其中最大的變化可能是React Hooks的加入,而最令人困惑的卻是它的生命周期,新舊生命周期函數(shù)混雜在一起,難免會(huì)讓許多新來者有很多困惑。所以這一篇我們來...

    MobService 評(píng)論0 收藏0
  • ReactV16.3,即將更改的生命周期

    摘要:我們目前的計(jì)劃是為不安全生命周期引入別名,和。從現(xiàn)在開始,只有新的生命周期名稱將起作用。從版本開始,更新以響應(yīng)更改的推薦方法是使用新的靜態(tài)生命周期。 注釋:本文是根據(jù)React的官方博客翻譯而成(文章地址:https://reactjs.org/blog/2018...)。主要講述了React之后的更新方向,以及對(duì)之前生命周期所出現(xiàn)的問題的總結(jié),之后的React將逐步棄用一些生命周期和...

    wendux 評(píng)論0 收藏0
  • React組件生命周期詳解

    摘要:組件生命周期構(gòu)造方法是對(duì)類的默認(rèn)方法,通過命令生成對(duì)象實(shí)例時(shí)自動(dòng)調(diào)用該方法。該生命周期可以發(fā)起異步請(qǐng)求,并。后廢棄該生命周期,可以在中完成設(shè)置渲染組件是一個(gè)組件必須定義的生命周期,用來渲染。該生命周期內(nèi)可以進(jìn)行。 React組件生命周期 constructor( ) 構(gòu)造方法 constructor是ES6對(duì)類的默認(rèn)方法,通過 new 命令生成對(duì)象實(shí)例時(shí)自動(dòng)調(diào)用該方法。并且,該方法是...

    learn_shifeng 評(píng)論0 收藏0
  • React.js 小書 Lesson20 - 更新階段的組件生命周期

    摘要:所以對(duì)于組件更新階段的組件生命周期,我們簡(jiǎn)單提及并且提供一些資料給大家。這里為了知識(shí)的完整,補(bǔ)充關(guān)于更新階段的組件生命周期你可以通過這個(gè)方法控制組件是否重新渲染。大家對(duì)這更新階段的生命周期比較感興趣的話可以查看官網(wǎng)文檔。 React.js 小書 Lesson20 - 更新階段的組件生命周期 本文作者:胡子大哈本文原文:http://huziketang.com/books/react...

    Yumenokanata 評(píng)論0 收藏0
  • React組件生命周期

    摘要:組件生命周期此文章適合之前的版本,,添加了一些新的生命周期函數(shù),同時(shí)準(zhǔn)備廢棄一些會(huì)造成困擾的生命周期函數(shù)。每個(gè)生命周期階段調(diào)用的鉤子函數(shù)會(huì)略有不同。 React組件生命周期 此文章適合 React@17 之前的版本,[email protected],添加了一些新的生命周期函數(shù),同時(shí)準(zhǔn)備廢棄一些會(huì)造成困擾的生命周期函數(shù)。所有如果在React@17 發(fā)布之前,這篇文章還是適用的。新的生命周期請(qǐng)看官...

    mgckid 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

最新活動(dòng)
閱讀需要支付1元查看
<