讓 React 元件百變的最關鍵方法:props
你知道嗎?
假設我們的網站真的是由樂高堆疊起來的,身為前端工程師的我們,該設計多少個元件呢?
或許,你會黃色的設計成一個,藍色的設計成一個,綠色的設計成一個…。如果你還考量到他們有幾隻腳的話,那你大概會設計成千上萬個元件。
事實上,一個元件是可以透過參數來改變本身的行為和樣式的。
因此上述這一個問題,在看完本章後,你心中或許就有解答了;不過,我要先註明,這一個問題其實不只有一種答案!
先了解學習重點
在這一篇文章中,你將學習到:
- 如何傳遞參數給下層元件
- 如何透過 props 接收上層元件傳遞的參數
前情提要
在上一篇文章中,我們將下方這四個元件組合在一起:
如果你還不太了解這是如何完成的,可以看看下方的程式:
這裡也附上尚未完成的 jsfiddle,開始本章前,或許你可以先試著完成這一步驟。
學習「如何透過 props 傳遞參數」
假設有一天,你的主管給你一個需求,必須有三個標題列,如下:
我知道這個需求真的很不 make sense,但現實往往就是那麼殘酷!
你可以從這張圖發現到下面這幾點變化:
- 主標題名稱都不一樣
- 子標題的項目數量也不一樣
- 當沒有待辦事項時,不再顯示項目數量,顯示「你已完成了所有工作」
那麼,你該怎麼做呢?
第一種方法,將每個標題列都定義成一個元件:
雖然你可能已經隱隱覺得這個方法是行不通的,但是我們還是先來看看程式會怎麼寫吧:
這會造成一個問題,如果以後需求再變化,有了 TodoHeader4, TodoHeader5 時,這整個專案會發生什麼事呢?
你發現相似的地方了嗎?
如果你再仔細看一下這些 TodoHeader,你會發現它們的排版都非常相似,只是裡頭塞的資料不一樣而已;因此,我們把它設計成一個元件試試看。
在上面這一支程式中,我們做了四件事情:
- 把「主標題」設定為變數 — headerName,因此你可隨意置換成物慾清單或者工作清單
- 把「未完成的項目數量」設定為變數—todoNumber,因此你可隨意設定為 99 或 0
- 在 JSX 中,取得 headerName 的變數
- 在 JSX 中,判斷 todoNumebr 是否為零,並組成要顯示的字串
在這支程式中,你會看到一些新的語法:
- <h1>{headerName}</h1>:
這是 JSX element 中,取得變數的方法 - const:
這是 ES6 規範中,定義常數的方法(請參考此篇) - `${todoNumber} 項…`:
這是 ES6 規範中,組合變數與字串的語法(請參考此篇)
不過,這個版本的 TodoHeader 元件,我們仍然把變數寫死在同一支程式中,要如何將它們往外拉呢?
每一個元件都有的 props
這一次,我們使用了 props 這個 Component API。在 React 中,一個元件要接收外部的參數,都可以從 props 中取得。
在上面這一支程式,也使用了 ES6 的新語法:Destructuring。
const { headerName, todoNumber } = this.props;// 等同於const headerName = this.props.headerName;
const todoNumber = this.props.todoNumebr;
那麼,原本 headerName 和 todoNumber 變數要定義在哪裡呢?
你可以從上面的程式中發現,原本的 TodoHeader1, TodoHeader2, TodoHeader3 消失了,我們共用了同一個元件 TodoHeader,並且透過屬性的方式定義每一個元件的 headerName 和 todoNumebr。
如果你心思更細一點,你或許會想問「為什麼 todoNumber={3} 是用大括號賦值呢?」
如果是字串,可以直接使用雙引號賦值,但是如果是變數或是數字,要用大括號。
看看完成後的程式碼
你可以看看 jsfiddle 的程式和最後出現的結果,或是:
重點整理
ReactJS
- 元件透過 this.props 接受參數
- 上層元件透過 element 的屬性傳遞參數到下層元件中
ES6
動手做,加深記憶
我們來試試看新的需求吧,加入一個搜尋框時,你該怎麼做呢?
下集預告
下一集,「設計容易重複使用的 React 元件」。我們將接續這次學習的,讓你設計的元件更容易的重複使用,盡情期待。