使用 Props 顯示資料

到目前為止,如果你重複使用 <Header /> 元件,它會顯示相同的內容。

index.html
function Header() {
  return <h1>Develop. Preview. Ship.</h1>;
}
 
function HomePage() {
  return (
    <div>
      <Header />
      <Header />
    </div>
  );
}

但如果你想傳遞不同的文字,或者因為從外部來源獲取資料而無法預先知道內容呢?

常規的 HTML 元素有屬性(attributes),你可以用來傳遞資訊片段以改變這些元素的行為。例如,改變 <img> 元素的 src 屬性會改變顯示的圖片;改變 <a> 標籤的 href 屬性會改變連結的目的地。

同樣地,你可以將資訊片段作為屬性(properties)傳遞給 React 元件,這些稱為 props。舉例來說,按鈕元件的可能變化如下:

顯示按鈕元件的 3 種變化:主要、次要和禁用狀態的示意圖

類似於 JavaScript 函式,你可以設計接受自訂參數(或 props)的元件,這些參數會改變元件的行為或在渲染到畫面時顯示的內容。然後,你可以從父元件將這些 props 傳遞給子元件。

注意: 在 React 中,資料沿著元件樹向下流動,這稱為 單向資料流。狀態(將在下一章討論)可以作為 props 從父元件傳遞給子元件。

使用 props

在你的 HomePage 元件中,可以像傳遞 HTML 屬性一樣,將自訂的 title prop 傳遞給 Header 元件:

index.html
function HomePage() {
  return (
    <div>
      <Header title="React" />
    </div>
  );
}

而子元件 Header 可以接受這些 props 作為它的第一個 函式參數

index.html
function Header(props) {
  return <h1>Develop. Preview. Ship.</h1>;
}

如果你使用 console.log() 輸出 props,會看到它是一個帶有 title 屬性的 物件

index.html
function Header(props) {
  console.log(props); // { title: "React" }
  return <h1>Develop. Preview. Ship.</h1>;
}

由於 props 是一個物件,你可以在函式參數中使用 物件解構 來明確命名 props 的值:

index.html
function Header({ title }) {
  console.log(title); // "React"
  return <h1>Develop. Preview. Ship.</h1>;
}

然後,你可以將 <h1> 標籤的內容替換為你的 title 變數。

index.html
function Header({ title }) {
  console.log(title);
  return <h1>title</h1>;
}

如果你在瀏覽器中打開檔案,會看到它顯示的是實際的單詞 "title"。這是因為 React 認為你打算在 DOM 中渲染純文字字串。

你需要一種方式告訴 React 這是一個 JavaScript 變數。

在 JSX 中使用變數

要使用 title prop,請添加 大括號 {}。這是一種特殊的 JSX 語法,允許你在 JSX 標記中直接寫入常規 JavaScript。

index.html
function Header({ title }) {
  console.log(title);
  return <h1>{title}</h1>;
}

你可以將大括號視為從「JSX 模式」進入「JavaScript 模式」的方式。你可以在大括號內添加任何 JavaScript 表達式(會計算為單一值的內容)。例如:

  1. 使用點記法的 物件屬性
example.js
function Header(props) {
  return <h1>{props.title}</h1>;
}
  1. 模板字面量
example.js
function Header({ title }) {
  return <h1>{`Cool ${title}`}</h1>;
}
  1. 函式的 返回值
example.js
function createTitle(title) {
  if (title) {
    return title;
  } else {
    return 'Default title';
  }
}
 
function Header({ title }) {
  return <h1>{createTitle(title)}</h1>;
}
  1. 三元運算子
example.js
function Header({ title }) {
  return <h1>{title ? title : 'Default Title'}</h1>;
}

現在你可以將任何字串傳遞給 title prop,或者如果你使用了三元運算子,甚至可以完全不傳遞 title prop,因為你已經在元件中處理了預設情況:

example.js
function Header({ title }) {
  return <h1>{title ? title : 'Default title'}</h1>;
}
 
function HomePage() {
  return (
    <div>
      <Header />
    </div>
  );
}

你的元件現在接受了一個通用的 title prop,可以在應用程式的不同部分重複使用。你只需要更改 title 字串:

index.html
function HomePage() {
  return (
    <div>
      <Header title="React" />
      <Header title="A new title" />
    </div>
  );
}

遍歷列表

通常你會有一些需要以列表形式顯示的資料。你可以使用陣列方法來操作資料,並生成樣式相同但包含不同資訊的 UI 元素。

將以下名稱陣列添加到你的 HomePage 元件中:

index.html
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li>{name}</li>
        ))}
      </ul>
    </div>
  );
}

然後,你可以使用 array.map() 方法遍歷陣列,並使用 箭頭函式 將名稱映射到列表項目:

index.html
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li>{name}</li>
        ))}
      </ul>
    </div>
  );
}

注意你是如何使用大括號在「JavaScript」和「JSX」模式之間切換的。

如果你執行這段程式碼,React 會警告我們缺少 key prop。這是因為 React 需要某些東西來唯一識別陣列中的項目,以便知道要更新 DOM 中的哪些元素。

目前你可以暫時使用名稱,因為它們目前是唯一的,但建議使用保證唯一的內容,例如項目 ID。

index.html
function HomePage() {
  const names = ['Ada Lovelace', 'Grace Hopper', 'Margaret Hamilton'];
 
  return (
    <div>
      <Header title="Develop. Preview. Ship." />
      <ul>
        {names.map((name) => (
          <li key={name}>{name}</li>
        ))}
      </ul>
    </div>
  );
}

延伸閱讀:

On this page