[譯] 如何寫出更好的 React 程式碼?

jonjia發表於2018-05-02

寫出更好的 React 程式碼的 9 條實用提示:瞭解程式碼檢查、propTypes、PureComponent 等。

[譯] 如何寫出更好的 React 程式碼?

使用 React 可以輕鬆建立互動式介面。為應用中的每個狀態設計簡單的檢視,當資料變化時,React 會高效地更新和渲染正確的元件。

這篇文章中,我會介紹一些使你成為更好的 React 開發者的方法。包括從工具到程式碼風格等一系列內容,這些都可以幫助你提升 React 相關技能。 ?


程式碼檢查

要寫出更好程式碼,很重要的一件事就是使用好的程式碼檢查工具。如果我們配置好了一套程式碼檢查規則,程式碼編輯器就能幫我們捕捉到任何可能出現的程式碼問題。

但除了捕捉問題,ES Lint 也會讓你不斷學習到 React 程式碼的最佳實踐。

import react from 'react';
/* 其它 imports */

/* Code */

export default class App extends React.Component {
  render() {
    const { userIsLoaded, user } = this.props;
    if (!userIsLoaded) return <Loader />;
    
    return (
      /* Code */
    )
  }
}
複製程式碼

看一下上面的程式碼。假設你想在 render() 方法中引用一個叫做 this.props.hello 的新屬性。程式碼檢查工具會馬上把程式碼變紅,並提示:

props 驗證沒有 'hello' (react/prop-types)
複製程式碼

程式碼檢查工具會讓你認識到 React 的最佳實踐並塑造你對程式碼的理解。很快,之後寫程式碼的時候,你就會開始避免犯錯了。

你可以去 ESLint 官網 為 JavaScript 配置程式碼檢查工具,或者使用 Airbnb’s JavaScript Style Guide。也可以安裝 React ESLint Package


propTypes 和 defaultProps

上一節中,我談到了當使用一個不存在的 prop 時,我的程式碼檢查工具是如何起作用的。

static propTypes = {
  userIsLoaded: PropTypes.boolean.isRequired,
  user: PropTypes.shape({
    _id: PropTypes.string,
  )}.isRequired,
}
複製程式碼

在這裡,如果 userIsLoaded 不是必需的,那麼我們就要在程式碼中新增說明:

static defaultProps = {
 userIsLoaded: false,
}
複製程式碼

所以每當我們要在元件中使用 引數型別檢查,就要為它設定一個 propType。如上,我們告訴 React:userIsLoaded 的型別永遠是一個布林值。

如果我們宣告 userIsLoaded 不是必需的值,那麼我們就要為它定義一個預設值。如果是必需的,就沒有必要定義預設值。但是,規則還指出不應該使用像物件或陣列這樣不明確的 propTypes。

為什麼使用 shape 方法來驗證 user 呢,因為它內部需要有一個 型別為字串的 id 屬性,而整個 user 物件又是必需的。

確保使用了 props 的每個元件都宣告瞭 propTypesdefaultProps,這對寫出更好的 React 程式碼很有幫助。

當 props 實際獲取的資料和期望的不同時,錯誤日誌就會讓你知道:要麼是你傳遞了錯誤的資料,要麼就是沒有得到期望值,特別是寫可重用元件時,找出錯誤會更容易。這也會讓這些可重用元件更可讀一些。

注意:

React 從 v15.5 版本開始,不再內建 proptypes,需要作為獨立的依賴包新增到你的專案中。

點選下面的連結瞭解更多:


知道何時建立新元件

export default class Profile extends PureComponent {
  static propTypes = {
    userIsLoaded: PropTypes.bool,
    user: PropTypes.shape({
      _id: PropTypes.string,
    }).isRequired,
  }
  
  static defaultProps = {
    userIsLoaded: false,
  }
  
  render() {
    const { userIsLoaded, user } = this.props;
    if (!userIsLoaded) return <Loaded />;
    return (
      <div>
        <div className="two-col">
          <section>
            <MyOrders userId={user._id} />
            <MyDownloads userId={user._id} />
          </section>
          <aside>
            <MySubscriptions user={user} />
            <MyVotes user={user} />
          </aside>
        </div>
        <div className="one-col">
          {isRole('affiliate', user={user._id) &&
            <MyAffiliateInfo userId={user._id} />
          }
        </div>
      </div>
    )
  }
}
複製程式碼

上面有一個名為 Profile 的元件。這個元件內部還有一些像 MyOrderMyDownloads 這樣的其它元件。因為它們從同一個資料來源(user)獲取資料,所以可以把所有這些元件寫到一起。把這些小元件變成一個巨大的元件。

儘管什麼時候才要建立一個新元件沒有任何硬性規定,但問問你自己:

  • 程式碼的功能變得笨重了嗎?
  • 它是否只代表了自己的東西?
  • 是否需要重用這部分程式碼?

如果上面有一個問題的答案是肯定的,那你就需要建立一個新元件了。

記住,任何人如果看到你的有 200–300 行的元件時都會抓狂的,然後沒人會想再看你的程式碼。


Component vs PureComponent vs Stateless Functional Component

對於一個 React 開發者,知道在程式碼中什麼時候該使用 ComponentPureComponentStateless Functional Component 是非常重要的。

你可能注意到了在上面的程式碼中,我沒有將 Profile 繼承自 Component,而是 PureComponent

首先,來看看無狀態函式式元件。

Stateless Functional Component(無狀態函式式元件)

const Billboard = () => (
  <ZoneBlack>
    <Heading>React</Heading>
    <div className="billboard_product">
      <Link className="billboard_product-image" to="/">
        <img alt="#" src="#">
      </Link>
      <div className="billboard_product-details">
        <h3 className="sub">React</h3>
        <p>Lorem Ipsum</p>
      </div>
    </div>
  </ZoneBlack>
);
複製程式碼

無狀態函式式元件是一種很常見的元件型別。它為我們提供了一種非常簡潔的方式來建立不使用任何 staterefs生命週期方法 的元件。

無狀態函式式元件的特點是沒有狀態並且只有一個函式。所以你可以把元件定義為一個返回一些資料的常量函式。

簡單來說,無狀態函式式元件就是返回 JSX 的函式。

PureComponents

通常,一個元件獲取了新的 prop,React 就會重新渲染這個元件。但有時,新傳入的 prop 並沒有真正改變,React 還是觸發重新渲染。

使用 PureComponent 可以幫助你避免這種重新渲染的浪費。例如,一個 prop 是字串或布林值,它改變後,PureComponent 會識別到這個改變,但如果 prop 是一個物件,它的屬性改變後,PureComponent 不會觸發重新渲染。

那麼如何知道 React 何時會觸發一個不必要的重新渲染呢?你可以看看這個叫做 Why Did You Update 的 React 包。當不必要的重新渲染髮生時,這個包會在控制檯中通知你。

[譯] 如何寫出更好的 React 程式碼?

一旦你確認了一個不必要的重新渲染,就可以使用 PureComponent 替換 Component 來避免。


使用 React 開發者工具

如果你真想成為一個專業的 React 開發者,那麼在開發過程中,就應該經常使用 React 開發者工具。

如果你使用過 React,你的控制檯很可能建議過你使用 React 開發者工具。

React 開發者工具適用於所有主流瀏覽器,例如:ChromeFirefox

通過 React 開發者工具,你可以看到整個應用結構和應用中正在使用的 props 和 state。

React 開發者工具是探索 React 元件的絕佳方式,也有助於診斷應用中的問題。


使用內聯條件語句

這個觀點可能會引起一些爭議,但我發現使用內聯條件語句可以明顯簡化我的 React 程式碼。

如下:

<div className="one-col">
  {isRole('affiliate', user._id) &&
    <MyAffiliateInfo userId={user._id} />
  }
</div>
複製程式碼

上面程式碼中,有一個檢查這個人是否是 “affiliate” 的方法,後面跟了一個叫做 <MyAffiliateInfo/> 的元件。

這樣做的好處是:

  • 不必編寫單獨的函式
  • 不必在 render 方法中使用 “if” 語句
  • 不必為元件中的其它位置建立“連結”

使用內聯條件語句非常簡潔。開始你可以把條件寫為 true,那麼 <MyAffiliateInfo /> 元件無論如何都會顯示。

然後我們使用 && 連線條件和 <MyAffiliateInfo />。這樣當條件為真時,元件就會被渲染。


儘可能使用程式碼片段庫

開啟一個程式碼編輯器(我用的是 VS Code),新建一個 js 檔案。

在這個檔案中輸入 rc,就會看見如下提示:

[譯] 如何寫出更好的 React 程式碼?

按下Enter鍵,會立刻得到下面的程式碼片段:

[譯] 如何寫出更好的 React 程式碼?

這些程式碼片段的優點不僅是幫助你減少 bug,還能幫助你獲取到最新最棒的寫法。

你可以在程式碼編輯器中安裝許多不同的程式碼片段庫。我用於 VS Code 的叫做 ES7 React/Redux/React-Native/JS Snippets


React Internals — 瞭解 React 內部如何工作

React Internals 是一個共五篇的系列文章,幫助我理解 React 的基礎知識,最終幫助我成為一個更好的 React 開發者!

如果你對某些問題不能完全理解,或者你知道 React 的工作原理,那麼 React Internals 可以幫助你理解何時、如何在 React 中做對的事。

這對那些不清楚在哪裡執行程式碼的人特別有用。

理解 React 內部執行原理會幫助你成為更好的 React 開發者。


在你的元件中使用 BitStoryBook

Bit 是一個將你的 UI 元件轉化為可以在不同應用中分享、開發和同步的構建塊的工具。

你也可以利用 Bit 管理團隊元件,通過 線上元件區,可以使它們容易獲取和使用,也便於單獨測試。

Storybook 是用於 UI 元件的快速開發環境,可以幫助你瀏覽一個元件庫,檢視每個元件的不同狀態,互動式開發和測試元件。

Storybook 提供了一個幫你快速開發 React 元件的環境,通過它,當你操作元件的屬性時,Web 頁面會熱更新,讓你看到元件的實時效果。


快速回顧

  1. 使用程式碼檢查工具,使用 ES Lint、Airbnb’s JavaScript Style Guide 和 ESLint React 外掛。
  2. 使用 propTypes 和 defaultProps。
  3. 知道何時建立新元件。
  4. 知道何時使用 Component、PureComponent 和 Stateless Functional Component。
  5. 使用 React 開發者工具。
  6. 使用內聯條件語句。
  7. 使用程式碼片段庫,節省浪費在樣板程式碼上的時間。
  8. 通過 React Internals 瞭解 React 如何工作。
  9. 使用像 Bit、StoryBook 這樣的工具來優化開發流程。

掘金翻譯計劃 是一個翻譯優質網際網路技術文章的社群,文章來源為 掘金 上的英文分享文章。內容覆蓋 AndroidiOS前端後端區塊鏈產品設計人工智慧等領域,想要檢視更多優質譯文請持續關注 掘金翻譯計劃官方微博知乎專欄

相關文章