1. 程式人生 > >[筆記]《深入淺出React和Redux》- 設計高質量的React元件

[筆記]《深入淺出React和Redux》- 設計高質量的React元件

1. 易於維護元件的設計要素

作為軟體設計的通則,元件的劃分要滿足高內聚(High Cohesion)和低耦合(Low Coupling)的原則。

 

高內聚指的是將邏輯緊密相關的內容放在一個元件中。使用者介面無外乎內容、互動行為和樣式。傳統上,內容由 HTML 表示,互動放在 JavaScript 程式碼檔案中,樣式放在 CSS 檔案中定義。這雖然滿足一個功能模組的需要,卻要放在三個不同的檔案中,這其實不滿足高內聚的原則。React 卻不是這樣,展示內容的 JSX、定義行為的 JavaScript 程式碼,甚至定義樣式的 CSS,都可以放在一個 JavaScript 檔案中,因為它們本來就是為了實現一個目的存在的,所以說 React 天生具有高內聚的特點。

 

低耦合指的是不同元件之間的依賴關係要儘量弱化,也就是每個元件要儘量獨立。

 

2. React 元件的資料

prop 和 state 的對比

  • prop 用於定義外部介面,state 用於記錄內部狀態;
  • prop 的賦值在外部世界使用元件時,state 的賦值在元件內部;
  • 元件不應該改變 prop 的值,而 state 存在的目的就是讓元件來改變的。

元件絕不應該去修改傳入的 props 的值,加入父元件包含多個子元件,然後把一個 JavaScript 物件作為 props 值傳給這一個子元件,而某個子元件居然改變了這個物件的內部值,那麼,接下來其他子元件讀取這個物件會得到什麼值呢?當時讀取了修改過的值,但是其他子元件是每次渲染都讀取這個 props 的值呢?還是隻讀一次以後就用那個最初值呢?一切皆有可能,完全不可預料。也就是說,一個子元件去修改 props 中的值,可能讓程式陷入一團混亂之中,這完全違背了 React 設計的初衷。

 

3. 元件的生命週期

3.1 裝載過程

  • constructor
  • getInitialState
  • getDefaultProps
  • componentWillMount
  • render
  • componentDidMount

在裝載過程中,componentWillMount 會在呼叫 render 函式之前被呼叫,componentDidMount 會在呼叫 render 函式之後被呼叫。

 

通常我們不用定義 componentWillMount 函式,顧名思義 componentWillMount 發生在“將要裝載”的時候,這個時候沒有任何渲染出來的結果,即使呼叫 this.setState 修改狀態也不會引發重新繪製,一切都遲了。

 

render 函式被呼叫完之後,componentDidMount 函式並不是會被立刻呼叫,componentDidMount 被呼叫的時候,render 函式返回的東西已經引發了渲染,元件已經被“裝載”到了 DOM 樹上。

 

componentWillMount 可以在伺服器端被呼叫,也可以在瀏覽器端被呼叫;而 componentDidMount 只能在瀏覽器端被呼叫,在伺服器端使用 React 的時候不會被呼叫。

 

3.2 更新過程

  • componentWillReceiveProps
  • shouldComponentUpdate
  • componentWillUpdate
  • render
  • componentDidUpdate

1. componentWillReceiveProps(nextProps)

只要是父元件的 render 函式被呼叫,在 render 函式裡面被渲染的子元件都會經歷更新過程,不管父元件傳給子元件的 props 有沒有改變,都會觸發子元件的 componentWillReceiveProps 函式。

 

2. shouldComponentUpdate(nextProps, nextState)

shouldComponentUpdate 函式決定了一個元件什麼時候不需要渲染。

 

3. componentWillUpdate 和 componentDidUpdate

和裝載過程不同的是,當在伺服器端使用 React 渲染時,這一對函式中的 Did 函式,也就是 componentDidUpdate 函式,並不是只在瀏覽器端才執行的,無論更新過程發生在伺服器端還是瀏覽器,該函式都會被呼叫。

 

使用 React 做伺服器端渲染時,基本不會經歷更新過程,因為伺服器端只需要產出 HTML 字串,一個裝載過程就足夠產出 HTML 了,所以正常情況下伺服器端不會呼叫 componentDidMount 函式,如果呼叫了,說明我們的程式有錯誤,需要改進。

 

3.3 解除安裝過程

React 元件解除安裝過程只涉及一個函式 componentWillUnmount,當 React 元件要從 DOM 樹上刪除掉之前,對應的 componentWillUnmount 函式會被呼叫,所以這個函式適合做一些請理性的工作。