Reactv16.8.6生命周期函數

来源:https://www.cnblogs.com/gaoguowen/archive/2019/07/31/11279629.html
-Advertisement-
Play Games

組件生命周期函數 React 主動調用的方法,也可重寫這些方法 "生命周期圖譜" 當組件實例被創建並插入 中時,其生命周期調用順序如下: constructor(props) 如果不需要初始化 state 或 不進行方法綁定,則不需要使用該方法 在組件掛載之前會先調用該方法,在實現構造函數時必須先調 ...


組件生命周期函數

React 主動調用的方法,也可重寫這些方法

生命周期圖譜

當組件實例被創建並插入 DOM 中時,其生命周期調用順序如下:

constructor(props)

如果不需要初始化 state 或 不進行方法綁定,則不需要使用該方法

在組件掛載之前會先調用該方法,在實現構造函數時必須先調用super(props)方法,否則會出現BUG
通常,構造函數僅用於兩種情況:1. 初始化 state 2. 為事件處理函數綁定實例
在該方法中不要使用 setState() 方法,在其他方法中使用setState()改變 state
為什麼 props 複製給 state 會產生 bug

constructor(props) {
  super(props);
  // 不要在這裡調用 this.setState()
  this.state = {
    counter: 0,
    name:props.name // 嚴禁這樣賦值,props.name值更新時 state.name並不會更新
   };
  this.handleClick = this.handleClick.bind(this);
}

static getDerivedStateFromProps() (此方法不常用)

此方法會在 render 方法之前調用,並且初始化和數據更新時都會調用,它返回一個對象更新 state,如果返回null 則不更新任何內容。

此方法適用於 state 值在任何時候都取決於props 的情況。

render()

render 是 class 組件必須實現的方法

當該方法被調用時,它會監測 props 和 state 的變化,並且返回以下類型之一:

  • React 元素:通過JSX創建,渲染成對應的DOM節點或自定義組件
  • 數組或fragments: 使render方法可以返回多個元素 frgments
  • Portals:可以渲染子節點到不同的DOM子樹匯中portals
  • 字元串或數值類型: 在DOM中會被渲染為文本節點、
  • Boolean 或 null:什麼都不渲染

render方法最好為純函數,即在不修改組件 state情況下,每次調用時都返回相同的結果,並且不會直接與瀏覽器交互

如果要和瀏覽器交互,可以在其他生命周期函數中執行,註意:shoouldComponentUpdate方法中返回false,將不會調用render方法

class Example extemds React.Component{
shouldComponentUpdate(nextProps, nextState){
  return false
}
render(){ // 不會執行
  <div>owen</div>
  }
}

componentDIdMount()

此方法會在組件掛載後(插入DOM樹中)調用,初始化的數據的好地方

組件的 propsstate 發生變化會觸發更新。組件更新的生命周期調用順序如下:

static getDerivedStateFromProps() (此方法不常用)(已解釋)

shouldComponentUpdate(nextProps, nextState) (此方法不常用)

當state 或 props 變化時該方法會在渲染執行前調用預設返回值為true,首次載入不會被調用

根據該方法的返回值判斷組件輸出是否受當前 state 或 props 更改的影響。預設為 state 每次更新重新渲染

此方法進僅做為性能優化的方式存在,不要企圖依靠此方法來“阻止”渲染,因為這可能會產生 bug。你應該考慮使用內置的 PureComponent 組件,而不是手動編寫 shouldComponentUpdate()。PureComponent 會對 props 和 state 進行淺層比較,並減少了跳過必要更新的可能性。

render()(已解釋)

getSnapshotBeforeUpdate() (此方法不常用)

此方法在最近一次渲染輸出(提交到DOM節點)之前調用。使組件能在發送更改前從DOM中捕獲一些信息(如 位置)。此生命周期的返回值將作為參數傳遞給 componentDidUpdate()

class ScrollingList extends React.Component {
  constructor(props) {
    super(props);
    this.listRef = React.createRef();
  }

  getSnapshotBeforeUpdate(prevProps, prevState) {
    // 我們是否在 list 中添加新的 items ?
    // 捕獲滾動​​位置以便我們稍後調整滾動位置。
    if (prevProps.list.length < this.props.list.length) {
      const list = this.listRef.current;
      return list.scrollHeight - list.scrollTop;
    }
    return null;
  }

  componentDidUpdate(prevProps, prevState, snapshot) {
    // 如果我們 snapshot 有值,說明我們剛剛添加了新的 items,
    // 調整滾動位置使得這些新 items 不會將舊的 items 推出視圖。
    //(這裡的 snapshot 是 getSnapshotBeforeUpdate 的返回值)
    if (snapshot !== null) {
      const list = this.listRef.current;
      list.scrollTop = list.scrollHeight - snapshot;
    }
  }

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

上述示例中,重點是從 getSnapshotBeforeUpdate 讀取 scrollHeight 屬性,因為 “render” 階段生命周期(如 render)和 “commit” 階段生命周期(如 getSnapshotBeforeUpdate 和 componentDidUpdate)之間可能存在延遲。

componentDidUpdate(prevProps, prevState, snapshot)

此方法會在數據更新後立即調用,首次載入不會被調用,在此方法中使用 setState必須將它放到條件語句中,否則會導致死迴圈。還會導致額外的重新渲染,影響性能

componentDidUpdate(prevProps) {
  // 典型用法(不要忘記比較 props):
  if (this.props.userID !== prevProps.userID) {
    this.fetchData(this.props.userID);
  }
}

註意:如果 shouldComponentUpdate() 返回值為 false,則不會調用 componentDidUpdate()。

當組件從 DOM 中移除時會調用如下方法:

componentWillUnmount()

此方法會在組件卸載銷毀前調用,可以執行必要的清理操作,如 定時器,取消網路請求,或清除componentDidMount() 中創建的訂閱等。

當渲染過程,生命周期,或子組件的構造函數中拋出錯誤時,會調用如下方法:

Error boundaries:捕獲渲染期間及整個樹的函數發送的錯誤,渲染降級 UI,但自身的錯誤無法捕獲 React 16中的錯誤處理

static getDerivedStateFromError(error) (此方法不常用)

次生命周期會在後代組件拋出錯誤後調用,將錯誤作為參數,返回一個值更新state,在渲染期間不允許出現副作用,建議使用 componentDidCatch()

componentDidCatch(error, info) (此方法不常用)

此方法在後代組件拋出錯誤後被調用

如果發生錯誤,可以通過調用 setState 使用 componentDidCatch() 渲染降級 UI,但在未來的版本中將不推薦這樣做。 可以使用靜態 getDerivedStateFromError() 來處理降級渲染。

class ErrorBoundary extends React.Component {
  constructor(props) {
    super(props);
    this.state = { hasError: false };
  }

  static getDerivedStateFromError(error) {
    // 更新 state 使下一次渲染可以顯降級 UI
    return { hasError: true };
  }
  componentDidCatch(error, info) {
    // "組件堆棧" 例子:
    //   in ComponentThatThrows (created by App)
    //   in ErrorBoundary (created by App)
    //   in div (created by App)
    //   in App
    logComponentStackToMyService(info.componentStack);
  }
  render() {
    if (this.state.hasError) {
      // 你可以渲染任何自定義的降級  UI
      return <h1>Something went wrong.</h1>;
    }

    return this.props.children;
  }
}

Example

class Square extends React.Component {

  constructor(props) {
    super(props);
    this.state = {
      value:null
    };
  }
  static getDerivedStateFromProps(props, state) {
    // 實例化組件之後以及在重新呈現組件之前調用新的靜態生命周期。它可以返回要更新的對象state,或null指示新對象props不需要任何state更新。
  }
   componentDidMount() { // 組件被渲染到 DOM 中後運行
    console.log('DidMount: 1')
  }

  shouldComponentUpdate(){
    // 更新前
  }

  getSnapshotBeforeUpdate(){
    //
  }
  componentDidUpdate() {
    // 更新後
  }

  static getDerivedStateFromError() {
      // 出錯時
  }
  componentDidCatch(){
    // capture error
  }
  compoentwillUnmount(){ // 組件被刪除的時候
    console.log('UnMount: end')

  }
  render() {
    return (
      <button className="square" onClick = {()=>{this.setState({value:'X'})}
      }>
        {this.state.value}
      </button>
    );
  }
}

Owen 的個人博客

參考資料:React官網


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • mysql中的統計函數: 1. 查詢商品價格中最高的價格: 2. 查詢商品價格中最低的價格: 3. 求庫存總量: 4. 查看所有商品的平均價格: 5. 統計商城內共有多少種商品(不是多少個): count()函數是統計行數值,之所以用count(*)而不用count(列名)是因為如果該列有一行為空, ...
  • isMemberOfClass - 調用者必須是傳入的類的實例對象才返回YES- 判斷調用者是否是傳入對象的實例,別弄反了,如 [s1 isMemberOfClass:p1] ,意思是s1是否是p1的實例對象- 去去父類遞歸查找判斷 源碼: 有兩個方法,一個類方法,一個對象方法,兩者區別: - 實例 ...
  • 簡書文章:https://www.jianshu.com/p/e1099a94b979 附搶紅包開源項目地址,代碼已全改為Kotlin了,已適配到最新微信7.0.5版本,如果對你有所幫助賞個star吧:https://github.com/xbdcc/GrabRedEnvelope 前言 相信很多人 ...
  • 前言 之前在網上有看到過一個短視頻,有人製作了一個自動上拉看下一條視頻 的物理外掛(ps:其實就是綁了一根筆在轉圈圈),作為android開發者,當 然看不上這麼"low“的物理外掛,因此有了以下的monkey腳本。 <! more 準備 工具:adb、打開了開發者模式的android手機 環境:m ...
  • 開發平臺搭建 Eclipse 版本:eclipse-jee-2018-09-win32-x86_64.zip,直接去Eclipse官網下載 SDK版本:android-sdk_r24.4.1-windows.zip,下載鏈接:https://www.androiddevtools.cn/ ADT版本 ...
  • 最近在做一個項目的時候,需要用到下拉框搜索,網上搜了半天沒找到想要的,決心自己動手寫一個。 首先看下效果圖: 左邊是輸入框,可以進行模糊查詢,右邊圖標進行選擇。代碼部分,我定義了五個參數,和一個自定義的方法,list:下拉框數組,_width:組件寬度,_height:組件高度,bind:actio ...
  • 好久都沒有寫博客了,昨天本來想寫的結果在伺服器上安裝mysql出了點意外,今天中午趁著午休的時間給安裝好了。主要的問題有mysql從8.0.12版本重新安裝到了5.7幾的版本,因為我電腦上的是5.7的版本,另外一個就是navicat連接伺服器資料庫一直有問題,就是許可權什麼的問題,跟著百度的一些文章解 ...
  • 封裝一個函數用來克隆對象: ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...