React 元件的 8 個關鍵決策
通過這些關鍵決策來標準化你的 React 開發
![選擇困難症](https://i.iter01.com/images/c59628cce42940c6cfc2f5bb614dff873ee46a16a0a0639ebf87e02944659ff3.jpg)
React 自 2013 年被開源以來,一直在迭代更新。當你在網上搜尋相關資訊時,可能會被一些使用了過時的方法的文章坑到。所以,現在在寫 React 元件時,你的團隊需要作出以下八個關鍵決策。
決策 1:開發環境
在編寫第一個元件之前,你的團隊需要就開發環境達成一致。太多選擇了……
![](https://i.iter01.com/images/7e2f3a7bedec69530df5257b73d3d9e7423f0e46ca0f6c7235871e2aef16aaba.png)
當然,你可以從頭開始構建 JS 開發環境,有 25% 的 React 開發者是這麼做的。我目前的團隊使用的是 create-react-app 的 fork,並擴充了一些功能,例如支援 CRUD 的 mock API、可複用的元件庫和增強的程式碼檢測功能(我們會檢測 create-react-app 忽略了的測試檔案)。我是喜歡 create-react-app 的,但這個工具可以幫助你比較許多不錯的替代方案。想在服務端進行渲染?可以瞭解下 Gatsby 或者 Next.js。你甚至可以考慮使用線上編輯器,例如 CodeSandbox。
決策 2:型別檢測
你可以忽略型別,也可以使用 prop-types、Flow 或者 TypeScript。需要注意的是,在 React 15.5 中,prop-types 被提取到了單獨的庫,因此按照較老的文章進行匯入會報警告(React 16 會報錯)。
社群在這個話題上依然存在著分歧:
![](https://i.iter01.com/images/44ac4e6baf6aecd75b4bd29b330c01bc6fe1ab44b17eea9ad2c88972c6609a15.png)
我更傾向於 prop-types,因為我發現它在 React 元件中提供了足夠的型別安全性,幾乎沒有任何阻礙。使用 Babel、Jest、ESLint 和 prop-types 的組合,我很少看到執行時的型別問題。
決策 3:createClass 和 ES 類
React.createClass 是原始 API,但在 15.5 中已被棄用。有點感覺我們將槍頭指向了 ES 類。不管怎樣,createClass 已經從 React 的核心中移除,並被歸類到 React 官方文件中一個名為“React without ES6”的頁面。所以很清楚的是:ES 類是趨勢。你可以使用 react-codemod 輕鬆地從 createClass 轉換為 ES 類。
決策 4:類和函式
你可以通過類或函式來宣告 React 元件。當你需要 refs 或者生命週期方法時,類很有用。這裡有儘可能考慮使用函式的 9 個理由。但值得注意的是,函式元件有一些缺點。
決策 5:狀態
使用普通的 React 元件狀態足以滿足大多數場景。狀態提升可以很好地解決狀態共享的問題。或者,你也可以使用 Redux 或 MobX:
![](https://i.iter01.com/images/e5e989cb2a5b9a16a453de3055367d54693cc6acfad1cef8102ac167aebafef8.png)
我是 Redux 的粉絲,但我經常使用普通的 React 狀態,因為它更簡單。就目前來看,我們已經上線了十幾個 React 應用程式,其中的兩個是值得使用 Redux 的。我更喜歡多個小型的、自治的應用程式而不是單個的大型的應用程式。
如果你對不可變狀態感興趣,這裡有一篇相關的文章,提到了至少有 4 種方式來保持狀態不可變。
決策 6:繫結
在 React 元件中,至少有半打方式可以處理繫結。這主要是因為現代 JS 提供了很多方法來處理繫結。你可以在建構函式中繫結,在 render 中繫結,在 render 中使用箭頭函式,使用類屬性或者裝飾器。這篇文章的評論裡有更多的選擇!每種方式都有其優點,但假設你覺得實驗性功能還不錯,我建議預設使用類屬性(也叫屬性初始值)。
這個投票是從 2016 年 8 月開始的。從那時起,類屬性越來越受歡迎,而 createClass 的歡迎程度則逐步降低。
![](https://i.iter01.com/images/a3640dae7219e4a6dfeaf2b78a6dd8eb2b67db358c99db6c244f77a9da7e8e66.png)
附註:許多人對於為什麼在 render 中使用箭頭函式和繫結可能存在問題而感到困惑。真正的原因是因為它使 shouldComponentUpdate 和 PureComponent 變得古怪。
決策 7:樣式
這裡的選擇變得非常多,有 50 多種方式來寫元件的樣式,包括 React 的內聯樣式、傳統的 CSS、Sass/Less、CSS Modules 和 56 個 CSS-in-JS 選項。不開玩笑,我在這個樣式模組化課程中詳細探索了 React 的樣式,下面是總結:
![](https://i.iter01.com/images/322e48773d251fb8132fd348e536c235d8ffb5455a1d96036bf0f5ab9c2c001f.png)
紅色代表不支援,綠色代表支援,灰色代表警告。
看看為什麼在 React 的樣式選擇中有這麼多的分歧?沒有明確的贏家。
![](https://i.iter01.com/images/09fde7f380d44ec6a6f9a1b4e08ebe008b545712aa0bed419a43179173d9e528.png)
看起來 CSS-in-JS 正在蒸蒸日上,而 CSS modules 正在每況愈下。
我目前的團隊使用 Sass 和 BEM,並樂在其中,但我也喜歡樣式元件。
決策 8:邏輯複用
React 最初採用 mixins 作為元件之間共享程式碼的機制。但是 mixins 有問題,現在被認為是有害的。你不能在 ES 類元件中使用 mixins,所以現在我們使用高階元件和渲染屬性(也叫子函式)在元件之間共享程式碼。
![](https://i.iter01.com/images/bb6bc73db412a55ff68c8a23fbb368d6ef92a8492ab8e00c3c2efba9f2e80ffa.png)
高階元件目前更受歡迎,但我更喜歡渲染屬性,因為它們通常更易於閱讀和建立。
其他決策
還有一些其他的決策:
- 你使用 .js 還是 .jsx 擴充名?
- 你會將每個元件放在其自己的資料夾中嗎?
- 你會要求每個元件即一個檔案嗎?你會在每個目錄寫一個 index.js 檔案來讓別人感到抓狂嗎?
- 如果使用 propTypes,你會在底部宣告它們,還是在其自身的類裡使用靜態屬性?你會儘可能深地宣告 propTypes 嗎?
- 你會傳統地在建構函式中初始化狀態,還是使用屬性初始化語法?
由於 React 大多是 JavaScript,所以你需要進行許多 JS 開發風格的決策,例如分號、尾隨逗號、格式化以及事件處理的命名。
選擇一個標準,然後自動化執行
所有的這一切,今天你可能會看到很多組合。
所以,下面這幾步是關鍵:
和你的團隊討論這些決策並把你們的標準寫成文件。
不要浪費時間在程式碼審查中手動檢查不一致。要求你的團隊都使用像 ESLint、eslint-plugin-react 和 prettier 這些工具。
需要重構現有的 React 元件?使用 react-codemod 來自動化該過程。
如果我忽略了其它的關鍵決策,請在評論中提出。
想了解更多關於 React 的資訊?⚛️
我在 Pluralsight(免費試用)上寫了很多 React 和 JavaScript 課程。
![](https://i.iter01.com/images/10c01986e2a93e07ec2d3d38f81e7b1b0a291c6db0e3b590955d6a8300826020.png)
Cory House 是 Pluralsight 上許多 JavaScript、React、程式碼整潔之道和 .NET 課程的作者。他是 reactjsconsulting.com 的首席顧問、VinSolutions 的軟體架構師、Microsoft 的最有價值專家,並且在國際上培訓軟體開發人員的軟體實踐,例如前端開發和程式碼整潔之道。Cory 在 Twitter 上 @housecor 釋出了很多關於 JavaScript 和前端開發的推文。
掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 Android、iOS、React、前端、後端、產品、設計 等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。