1. 程式人生 > 其它 >React剖析之元件基礎

React剖析之元件基礎

React 介紹

它是一個用於構建使用者介面的JavaScript庫,通過元件化的方式解決檢視層開發複用的問題,本質是一個元件化框架。

宣告式、元件化、通用性(一次學習,隨處編寫)

  • 宣告式?
  • 元件化?
  • 通用性?

為什麼React要用JSX

JSX 是一個 JavaScript 的語法擴充套件,或者說是一個類似於 XML 的 ECMAScript 語法擴充套件,程式碼更簡潔,可讀性更強

JSX 主要用於宣告 React 元素,但 React 中並不強制使用 JSX。即使使用了 JSX,也會在構建過程中,通過 Babel 外掛編譯為 React.createElement。所以 JSX 更像是 React.createElement 的一種語法糖。

如何避免生命週期中的坑

只有React類元件有生命週期,函式式元件並沒有生命週期的概念,因為它本身是一個函式,只會從頭執行到尾。

1,constructor 被去除

  • constructor 中並不推薦去處理初始化以外的邏輯;
  • 本身 constructor 並不屬於 React 的生命週期,它只是 Class 的初始化函式;
  • 通過移除 constructor,程式碼也會變得更為簡潔。

2,在 componentDidMount 中發起網路請求

  • 如果在UNSAFE_componentWillMount中發起請求,由於React的非同步渲染機制,該方法可能會被多次呼叫。
  • 頁面渲染完畢後再呼叫介面,避免了因為錯誤請求導致的頁面渲染不出來的問題,影響使用者體驗感

3,shouldComponentUpdate 常用於效能優化

  • 通過新增判斷條件來阻止不必要的渲染

  • PureComponent 是React官方提供的通用的優化方案

    PureComponent 的核心原理就是預設實現了shouldComponentUpdate函式,在這個函式中對 props 和 state 進行淺比較,用來判斷是否觸發更新。

4,componentWillUnmount 主要用於執行清理工作

​ 一個比較常見的 Bug 就是忘記在 componentWillUnmount 中取消定時器,導致定時操作依然在元件銷燬後不停地執行。所以一定要在該階段解除事件繫結,取消定時器。

5,render 執行渲染

  • render函式應該是一個純函式,不應該在裡面產生副作用,比如呼叫setState或者繫結事件
  • 為什麼不能 setState 呢?因為 render 函式在每次渲染時都會被呼叫,而 setState 會觸發渲染,就會造成死迴圈。
  • 為什麼不能繫結事件呢?因為容易被頻繁呼叫註冊。

渲染

  • 函式元件任何情況下都會重新渲染,它並沒有生命週期,但官方提供了一種優化手段,那就是React.memo.

    const MyComponent = React.memo(function MyComponent(props) {
      /* 使用 props 渲染 */
    });
    

    React.memo 並不是阻斷渲染,而是跳過渲染元件的操作並直接複用最近一次渲染的結果,這與 shouldComponentUpdate 是完全不同的。

  • React.Component

    如果不實現 shouldComponentUpdate 函式,那麼有兩種情況觸發重新渲染。

    • 當 state 發生變化時。這個很好理解,是常見的情況。
    • 當父級元件的 Props 傳入時。無論 Props 有沒有變化,只要傳入就會引發重新渲染。
  • React.PureComponent

    PureComponent 預設實現了 shouldComponentUpdate 函式。所以僅在 propsstate 進行淺比較後,確認有變更時才會觸發重新渲染。

類元件與函式元件的區別:

相同點

  • 元件是React可複用的最小程式碼片段,無論是函式元件還是類元件,在使用方式和最終呈現效果上是一樣的

不同點

  • 設計思想不同。類元件是面向物件程式設計,所以有繼承,有屬性,有內部狀態的管理;函式元件是函數語言程式設計,主打的是 immutable、沒有副作用、引用透明等特點,輸入與輸出存在某種特定的對映關係,輸入一定的情況下,輸出必然是一定的。

    相較於類元件,函式元件更純粹、簡單、易測試 (本質上最大的區別)

  • 類元件有生命週期,函式元件沒有生命週期,可通過高階元件包裹函式來模擬生命週期,但現在有了hooks,這一點區別也就不存在了

  • 設計模式,類元件可繼承,函式元件不可繼承。但React中不推薦繼承已有的元件,因為靈活性很差

    組合優於繼承

  • 效能優化:類元件通過 shouldComponentUpdate 函式阻斷渲染,函式元件通過 React.memo 來優化。React.memo 不是阻斷渲染而是直接跳過渲染,採用上一次的渲染結果。

類元件不及函式元件的原因:

  • this的模糊性;

  • 業務邏輯散落在生命週期中;

  • React 的元件程式碼缺乏標準的拆分方式

  • hooks的函式元件可以提供比原先更細粒度的邏輯組織與複用,

    針對同一個功能的程式碼整合度更高,複用性更強

如何設計React元件?

展示元件的複用性更強,狀態元件則更專注於業務本身。

針對高階元件,refs屬性不能透傳,可通過 React.forwardRef 解決