v19.2Latest

向元件傳遞 Props

React 元件使用props來互相溝通。每個父元件都可以透過給予 props 來傳遞一些資訊給它的子元件。Props 可能會讓你想起 HTML 屬性,但你可以透過它們傳遞任何 JavaScript 值,包括物件、陣列和函式。

您將學習
  • 如何向元件傳遞 props
  • 如何從元件讀取 props
  • 如何為 props 指定預設值
  • 如何傳遞一些 JSX 給元件
  • Props 如何隨時間變化

熟悉的 props

Props 是你傳遞給 JSX 標籤的資訊。例如,classNamesrcaltwidthheight 是你可以傳遞給 <img>的一些 props:

你可以傳遞給 <img>標籤的 props 是預先定義的(ReactDOM 遵循HTML 標準)。但你可以傳遞任何 props 給你自己的 元件,例如 <Avatar>,以自訂它們。方法如下!

向元件傳遞 props

在這段程式碼中,Profile元件沒有傳遞任何 props 給它的子元件Avatar

你可以透過兩個步驟給予Avatar一些 props。

步驟 1:向子元件傳遞 props

傳遞一些 props 給Avatar。例如,讓我們傳遞兩個 props:person(一個物件)和size(一個數字):

注意

如果 person=後面的雙大括號讓你困惑,請回想它們僅僅是 JSX 大括號內的一個物件

現在你可以在 Avatar元件內部讀取這些 props。

步驟 2:在子元件內部讀取 props

你可以透過在 person, size後面列出它們的名稱,並用逗號分隔,直接放在({})內部來讀取這些 props。這讓你可以像使用變數一樣在function Avatar 之後的 Avatar 程式碼內部使用它們。

Avatar中加入一些使用personsizeprops 來渲染的邏輯,你就完成了。

現在你可以透過不同的 props 來配置Avatar,以多種不同的方式渲染。試著調整數值!

Props 讓您可以獨立地思考父元件和子元件。例如,您可以在 personsizeprops,而無需考慮Profile 內部更改 Avatar如何使用它們。同樣地,您可以更改Avatar如何使用這些 props,而無需查看Profile

您可以將 props 視為可以調整的「旋鈕」。它們扮演的角色與函數的參數相同——事實上,props就是您元件的唯一參數!React 元件函數接受單一參數,即一個props物件:

通常您不需要整個 props物件本身,因此您可以將其解構為單獨的 props。

陷阱

不要遺漏宣告 props 時{}這對大括號

這種語法稱為 「解構」,等同於從函數參數讀取屬性:

為 prop 指定預設值

如果您想為 prop 指定一個預設值,以便在未指定值時回退使用,可以在解構時於參數後直接加上= 和預設值:

現在,如果渲染<Avatar person={...} /> 時沒有 sizeprop,size 將被設為 100

僅當 sizeprop 缺失或您傳遞size={undefined}時才會使用預設值。但如果您傳遞size={null}size={0},則預設值 不會被使用。

使用 JSX 展開語法傳遞 props

有時,傳遞 props 會變得非常重複:

重複的程式碼本身沒有問題——它可能更具可讀性。但有時您可能更重視簡潔性。有些元件會將所有 props 轉發給其子元件,就像這個ProfileAvatar所做的那樣。由於它們不直接使用任何 props,因此使用更簡潔的「展開」語法可能更合理:

這會將 Profile的所有 props 轉發給Avatar,而無需逐一列出它們的名稱。

請謹慎使用展開語法。如果您在每個其他元件中都使用它,那就有問題了。通常,這表示您應該拆分元件並將子元件作為 JSX 傳遞。接下來會詳細說明!

將 JSX 作為子元件傳遞

巢狀內建瀏覽器標籤是很常見的:

有時你會希望以相同的方式嵌套自己的元件:

當你在 JSX 標籤內嵌套內容時,父元件會透過一個名為 children的 prop 接收該內容。例如,下面的Card元件將收到一個設定為children的 prop,其值為<Avatar />,並在一個包裝 div 中渲染它:

試著將 <Avatar>替換為一些文字,看看<Card>元件如何包裝任何嵌套內容。它不需要「知道」內部渲染的是什麼。你會在許多地方看到這種靈活的模式。

你可以將帶有 childrenprop 的元件視為一個「洞」,可以由其父元件用任意的 JSX 來「填充」。你經常會將childrenprop 用於視覺包裝器:面板、網格等。

一個類似拼圖的 Card 圖塊,帶有用於「children」片段的插槽,例如文字和 Avatar

插圖由Rachel Lee Nabors

Props 如何隨時間變化

下面的Clock 元件從其父元件接收兩個 props:colortime。(父元件的程式碼已省略,因為它使用了狀態,我們暫時不會深入探討。)

試著在下面的選擇框中更改顏色:

這個例子說明 元件可能會隨時間接收不同的 props。Props 並不總是靜態的!在這裡,timeprop 每秒變化一次,而colorprop 在你選擇另一種顏色時變化。Props 反映了元件在任何時間點的資料,而不僅僅是在開始時。

然而,props 是不可變的——這是一個來自電腦科學的術語,意為「不可更改」。當一個元件需要更改其 props(例如,響應用戶互動或新資料)時,它必須「請求」其父元件傳遞不同的 props——一個新的物件!其舊的 props 將被丟棄,最終 JavaScript 引擎會回收它們佔用的記憶體。

不要嘗試「更改 props」。 當你需要響應用戶輸入(例如更改選中的顏色)時,你需要「設定狀態」,你可以在 狀態:元件的記憶體 中學習。

總結

  • 要傳遞 props,請將其添加到 JSX 中,就像處理 HTML 屬性一樣。
  • 要讀取 props,請使用function Avatar({ person, size }) 解構語法。
  • 您可以指定一個預設值,例如size = 100,它用於缺失和 undefined的 props。
  • 您可以使用 <Avatar {...props} />JSX 展開語法轉發所有 props,但請勿過度使用!
  • 巢狀 JSX,例如<Card><Avatar /></Card> 將作為 Card 元件的 childrenprop 出現。
  • Props 是唯讀的時間快照:每次渲染都會收到一個新版本的 props。
  • 您無法更改 props。當您需要互動性時,您需要設定狀態。

Try out some challenges

Challenge 1 of 3:Extract a component #

This Gallery component contains some very similar markup for two profiles. Extract a Profile component out of it to reduce the duplication. You’ll need to choose what props to pass to it.