團隊不只有你,打造一個防呆的 React 元件

Jason Chung
前端魔法研究室
6 min readMar 18, 2016

--

我們都知道

一個 React 元件,可以透過參數(props)來改變自身的行為和樣式。

但是,你知道這個 API 的最大優點是什麼嗎?

我們可以更容易得設計出「重複再利用」的 React 元件

但是,一個優良的 reusable component 不止於此

你可以先問自己下面這三個問題:

Q1: 你做的元件要給誰使用呢?
A: 資深大大、資淺同仁、外包工程師,或是未來的自己。

Q2: 當你使用別人寫的程式或 API 時,你最需要的是什麼呢?
Ps. 請同理心的跟我想像一下~
A: 原始碼、API 文件、程式註解,或者正確的錯誤訊息。

Q3: 承 Q2,為什麼你需要這些呢?

千萬不要相信自己的記憶

如果你有認真得思考過上面三個問題,那麼最後一題,你的答案是否也是「方便開發、方便除錯、減少臭蟲、節省時間」呢?!

我想,你或許有經歷過看不懂自己前幾天寫的程式在表達什麼的時候,或是連以前經手的 API 都不會用的時刻。

那麼,你應該會了解「防呆」的重要;因為我們的腦袋並不是專職來牢記自己曾經寫過什麼的啊!

學習重點

為了讓自己的設計的元件更易於重複再利用;本章節,我們將學習到如何開發一個可以防呆的 React 元件,透過下面兩種方式:

  1. 定義元件的預設參數
  2. 定義元件參數的型別檢查

前期提要

上一篇文章中,我們遇到了下面這個需求:

顯示三種不同資料的標題列

因此我們設計了一個共用元件 TodoHeader:

該元件可以接收外部傳遞進來的參數(headerName, todoNumber),並且根據這兩個參數來達到顯示不同資料的需求

而外層的 TodoApp,我們組合了三個 TodoHeader:

這三個 TodoHeader 因為給予的參數不一樣,而有不一樣的樣貌

最後,我們完成的程式請參考 jsfiddle
Ps. 這一支程式也包括了上一篇文章的動手做唷!

學習「如何定義預設參數」

先瞭解我們的設計為什麼還不是優良的 reusable component

你有沒有想過當我們的 TodoApp 沒遞參數給 TodoHeader 會發生什麼事呢?

程式碼:將 TodoHeader 原本的屬性(headerName, todoNumber)移除
結果:移除屬性前 vs. 移除屬性後

你可以發現因為沒有定義 headerName 和 todoNumber 兩個屬性,所以頁面上沒有顯示主標題,且原本數字的部分也變成了 undefined。

「很正常吧?」

邏輯上,非常的正常!但是你可曾考慮到你的同事或未來的你,不小心的沒給到其中一個參數時,你會給你的客戶擁有了非常不正常及非常不舒適的體驗呢!

解決辦法:定義初始參數(defaultProps)

你有下面兩種方法設定元件的初始參數:

1. 如果你使用的 ES6 的 classes 定義元件,你可以使用 .defaultProps 來設定初始參數
2. 如果你使用的是 React.createClass 這支 API 定義元件,你可以透過實作 getDefaultProps 方法,並且回傳初始值的物件

或許,你會想問一定要所有接收的 props 都設定 defaultProps 嗎?
答案是不一定的!如果在 render 前你有考量到其他開發者可能沒給予這個參數並作一些處理,或是你認為沒給該參數也沒有太大的影響,那麼你就可以忽略這個步驟。

但是,如果某一個參數是必須要給予,而且沒設定初始參數的必要的話,該怎麼提醒其他開發者呢?

學習「如何定義參數的型別檢查」

承上一章節最後一個問題,React 提供了另外一種解決方法幫助你開發優良的 reusable component。

先讓我們了解問題所在

這次,請想像你是你的客戶,而你看到了以下的畫面:

你發現了嗎?我到底有幾項未完成的待辦事項呢?

現在,讓我們回到工程師的角色,追一下程式到底發生了什麼事情:

你找到 bug 了嗎?todoNumber 是什麼時候被給予成 ‘我的待辦清單’ 的呢?

「現實世界中,真的會發生這種愚蠢的錯誤嗎?」

非常可惜的是,就是會!或許是你同事,甚至是你!可能當時 copy/paste 太倉促了,或者下午少喝了一杯咖啡,並且讓這個小小的 bug 就這樣埋藏於程式海之中。

然後某一天,你的電話就響起了…

解決辦法:定義參數的型別檢查(propTypes)

想當然的,React 也提供了解決辦法,因為 React 最重要的優點就是元件,元件最重要的優點就是重複使用。

你應該也知道 JS 是一個弱型別語言,這讓出錯的機率更常發生了。因此它提供了下面兩種方法定義參數的型別:

1. ES6 classes: 使用 .propTypes 定義參數的型別
2. React.createClass API: 定義 propTypes 屬性

在上面的程式中,你可能會好奇 React.PropTypes 是什麼,它是內建的型別檢查器。當你定義了某個參數應該要用哪一個檢查器後,在下層元件接收上層元件遞進來的參數前,參數的值會經過檢查器,來判斷該值是否正確。

想見更多 React.PropTypes,請參見官方文件

如果你好奇是否客製化自己的檢查器呢?可以的,更多內容也參考上方的官方文件連結!

重點整理

  1. 如何使用 defaultProps 定義元件的預設參數
  2. 如何使用 propTypes 定義元件參數的型別檢查
  3. 如何設計一個優良的 reusable component,除了透過 props,你還需要 defaultProps 和 propTypes

動手做,加深記憶

這支 jsfiddle 是已經完成 TodoHeader 的 defaultProps 和 propTypes 的程式。我們可以說 TodoHeader 已經算是一個設計優良的 reusable component。

現在,請將 InputField 也設計成你心中優良的 reusable component 吧!

下一集預告

下一集,「動態產生多個 React 元件」。我們將學習如何根據一個值陣列產生多個元件,譬如說:產生待辦事項的清單,所以盡情期待囉。

你應該會想看的

上一篇系列文章

文件

ReactJS: Reusable Components

--

--