編寫 React 元件的最佳實踐

發表於2017-02-26

144905_Iw2e_2903254

在我第一次編寫 React 程式碼的時候,我見發現許多不同的方法可以用來編寫元件,不同教程教授的內容也大不相同。儘管從那時候起框架已經相當成熟,但並沒有一種固定的“正確”方式指導。

在 MuseFind 工作的一年裡,我們的團隊編寫了許多 React 元件,後期我們對方法進行了優化直到滿意為止。

本指南描述了我們推薦的最佳實踐,不管你是一名初學者還是有經驗的老手,希望它能對你有所幫助。

在我們開始之前,有幾個地方要注意一下:

  • 我們使用的是 ES6 和 ES7 的語法。
  • 如果你對於現實和容器元件兩者之間的區別不甚明瞭,建議首先閱讀一下這個
  • 如果有任何建議、疑問或者感想,請通過評論來讓我們知曉。

基於類的元件

基於類的元件具有豐富狀態而且可以含有方法。我們要儘可能有節制地去使用,因為它們也有特定的適用場合。

讓我們使用一行一行的程式碼逐步地將我們的元件構建起來吧。

引入 CSS

我喜歡在 JavaScript 中操作 CSS,這在理論上這樣做是可行的。不過它仍然是一種新的創意,還沒出現切實可行的解決方案。不過在此之前,我們可以先為每一個元件引入一個 CSS 檔案。

我們也通過另寫一行將依賴引入從本地引入獨立了出來。

狀態初始化

如果你使用的是 ES6 而不是 ES7, 就在構造器中進行狀態初始化。否則,就使用這裡的 ES7 方式。更多內容可以在這裡找到。

我們也要確保會預設將類匯出。

propTypes 和 defaultProps

propTypes 和 defaultProps 是靜態屬性,要在元件程式碼中儘可能高的位置進行宣告。它們作為文件放在醒目的位置,其他開發者閱讀此檔案時能立即看到。

所有的元件都應該有 propTypes。

方法

有了類元件,在你想子元件傳遞方法時,就得去確認它們在被呼叫到時所持有的 this 物件是正確的。這個一般可以通過將 this.handleSubmit.bind(this) 傳遞給子元件來達成。

我們認為這種方式更加乾淨且容易,藉助 ES6 的箭頭函式可以自動地維護好正確的上線文。

屬性析構

擁有許多屬性的元件要讓每個屬性都另起一行,如上所示。

裝飾器

如果你使用了一些像 mobx 的東西,就可以像上面這樣對類元件進行裝飾 — 這樣做跟將元件傳遞給一個函式是一樣的效果。

裝飾器是一種用來修改元件功能的靈活且可讀性好的方式。我們對其進行了廣泛的運用,包括 mobx 還有我們自己的 mobx-models 庫。

如果你不想使用裝飾器,可以這樣做:

閉包

要避免向子元件傳遞新的閉包,如下:

原因: 每次父元件渲染時,都會有一個新的函式被建立並傳遞給輸入。

如果輸入是一個 React 元件,不管它的其它屬性實際是否已經發生了變化,都會自動地觸發讓它重新渲染。

調和是 React 中消耗最昂貴的部分,因此不要讓它的計算難度超過所需! 另外,傳遞一個類方法更容易閱讀、除錯和修改。

如下是完整的元件程式碼:

函式式元件

這些元件沒有狀態和方法。它們就是單純的元件,容易理解。要儘可能常去使用它們。

propTypes

這裡,我們將 propTypes 分配給了頂部一行的變數。在元件宣告的下面,我們對它們進行了正常的分配。

對 Props 和 defaultProps 進行析構

我的元件是一個函式,因此可以將它的屬性看做是引數。我們可以像下面這樣對它們進行擴充套件:

注意,我們也能以一種高度可讀的方式使用預設引數來扮演 defaultProps 的角色。如果 expanded 是 undefined, 我們就會將其設定為 false。 (這個例子有點勉強,因為是一個布林值,不過本身對於避免物件的“Cannot read <property> of undefined“這樣的錯誤是很有用的)。

要避免如下這種 ES6 語法:

看著非常現代,不過這裡的函式實際上沒有被命令。

這樣子的名稱在 Bable 進行了正確的設定的情況下是可行的 —  但如果沒有正確設定,任何錯誤都會以在<<anonymous>>中出現的方式顯示,除錯起來相當麻煩。

無名的函式也會在 Jest 這個 React 測試庫中引發問題。為了避免潛在的複雜問題出現,我們建議使用 function 而不是 const。

封裝

因為在函式式元件中不能使用裝飾器,所以你可以簡單地將它傳遞到函式中充當引數:

如下是完整的元件程式碼:

JSX 中的條件分支

你會有不少機會去做許多條件分支渲染。如下是你想要去避免的情況:

145744_fXZH_2903254

巢狀的三元組並非不是好主意。

有一些庫可以解決這個問題 (JSX-Control Statements),不過相比引入額外的依賴,通過如下這種方式解決複雜條件分支問題要更好:

145819_xtir_2903254

使用花括弧封裝一個 IIFE, 然後在裡面放入 if 語句,可以返回任何你想要渲染的東西。注意像這樣的 IIFE 對效能會有影響,不過在大多數情況中還不足以讓我們為此選擇丟掉可讀性。

還有就是當你只想要在一個條件分支中渲染一個元素時,比起這樣做…

… 使用短路寫法更划算:

 

相關文章