[誰來跟我 React 一下] 元件2: 傳遞資料 Props

為什麼需要?能做什麼?怎麼使用?

YiChe Liu
7 min readMar 22, 2022

由於 State 的改變是非同步的,改變時也可能造成不必要的重新渲染,所以如果有其他方式能取代 State 是最好的。加上 React 本來就推崇元件化,要將資料從父元件傳遞到子元件裡,就需要 Props 來幫忙。

前言

沿用上篇的例子,假設我們現在要將 menu list 單獨拉出來變成一個能被重複使用的元件(好讓每個頁面都能看見美味菜單),首先要做的當然是建立一個 MenuList.js 的元件檔:

接著,在要引入該元件的頁面中 import 並引入…

登愣,報錯了。

這是理所當然的,因為每個元件中的 data 都獨立存在。換句話說,在 MenuList 這個元件中無法取得 Home 元件的 data 。

雖然我們當然也可以原封不動把 Home 裡的資料搬到 MenuList 中,但如果今天有另一個頁面元件也要引入 MenuList ,而他需要的資料陣列,偏偏和 Home 需要的不一樣,那該怎麼辦呢?又或者是, Home 這個頁面引入五個元件,而這些元件需要的資料其實都大同小異,如果在元件各自取資料,好像又太過累贅,要如何改寫程式碼呢?

Props

講了這麼久終於要讓主角登場。 Props 可以讓資料從父元件單向傳遞到子元件當中,單向傳遞的意思就是不能改變的意思。在上面的例子裡, Home.js 是父元件, MenuList 則是子元件。透過 Props ,我們終於能把資料放在 Home.js ,並讓 MenuList 來引用他的資料。

改寫一下 Home.js :

<MenuList> 裡前面的 menu 代表子元件取用資料使用的名稱,後面的代表要傳遞的資料。除了傳遞陣列,也可以傳入普通的字串。

接著改寫 MenuList.js :

傳入的資料會放入函式參數中,可以命名為 Props 。 Props 傳遞的資料會被放在一個物件當中,裡頭則用剛剛在父元件命名的名稱作為屬性名。舉例來說,要取用剛才的 menu 陣列資料要打:

const menu = props.menu;

不過這種寫法還是有點太囉唆。讓我們在本來寫 Props 的位置,改成直接放入這個元件要使用的 Props 物件屬性名稱。

上述寫法和 Props example-2 (MenuList.js) 能達成完全相同的結果。

重複使用元件

如同前面所說, Props 可以幫助我們達成重用元件的目標。簡單舉個例子, Home 頁有兩個區塊,一個區塊要顯示所有的菜單,另一個只顯示有用到蛋的菜單。

可以知道其實我們只需要一個 menu 陣列,列出全部資料,再做篩選就好。請看看下面實際撰寫的範例:

聰明的你一定已經發現了,透過 Props ,只用一個 Home.js 和一個 MenuList.js 就能夠生成好幾個不同內容物的區塊。假設今天資料不是寫死在程式碼,而是去跟資料庫要,只取一次資料可以大幅縮短跑頁面的時間。當然,也會更容易維護。

Props 與函式

雖然 Props 不可改變,但可以把父元件的 set 函式當成 Props 傳給子元件,在子元件呼叫父元件的 State 更改後重渲染,只要父元件的 State 有更新, State 值就會再變成新的 Props 傳給子元件。

除此之外,要將子元件的資料傳給父元件,也可以透過 Props 搭配函式。舉例來說,假設這是一個產品管理後台,而我要在每個產品後面加上刪除按鈕。刪除按鈕本身被放在子元件,但處理刪除的函式 handleDelete 被放在父元件。為了讓 handleDelete 能判斷哪一項要被刪除,必須從子元件傳要刪除的 id 到父元件。我們可以用下面的方式來撰寫。

嘿,別忘了!對 React 來說,要更動資料必須要透過 setState() 。並且,要使用函式傳遞參數,外頭要包上一個大括號。

onClick 等號後面放大括號,函式才能正確傳遞參數
取得子元件傳過來的 id ,和 menu 裡每一項產品比較,只留下不同的,再用 setMenu 更新資料

你可能會覺得奇怪,幹嘛不把 handleDelete() 放在子元件就好,省得麻煩。這是因為 setMenu() 是在父元件被定義的,資料也在父元件初始化,最重要的是我們也不該去直接從子元件更動傳進來的 Props 值!所以最好還是回到父元件做處理。

比較 State 與 Props

最後來比較一下 State 和 Props 的差異。

  • State 是讓元件控制自己本身,可以被改變
  • Props 是讓外面的父元件對自己進行配置,唯讀不能改變

系列連結

Medium 不太好找前後篇文章,所以在這個系列文章最後,放入任意門連結,希望能幫助到你!

--

--

YiChe Liu
YiChe Liu

Written by YiChe Liu

小菜鳥前端 / 親手打過的筆記才是自己的

No responses yet