描述 UI

React 是一個用於渲染使用者介面 (UI) 的 JavaScript 函式庫。UI 由按鈕、文字和圖片等小單元建構而成。React 讓你將它們組合成可重複使用、可巢狀的元件。從網站到手機應用程式,螢幕上的所有內容都可以分解成元件。在本章中,你將學習如何建立、自定義和有條件地顯示 React 元件。

你的第一個元件

React 應用程式是由稱為元件的獨立 UI 片段建構而成。React 元件是一個 JavaScript 函式,你可以在其中穿插標記。元件可以小到一個按鈕,也可以大到整個頁面。這裡是一個渲染三個 Profile 元件的 Gallery 元件

function Profile() {
  return (
    <img
      src="https://i.imgur.com/MK3eW3As.jpg"
      alt="Katherine Johnson"
    />
  );
}

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

準備好學習這個主題了嗎?

閱讀你的第一個元件,學習如何宣告和使用 React 元件。

閱讀更多

匯入和匯出元件

你可以在一個檔案中宣告許多元件,但大型檔案可能會難以瀏覽。為了瞭解決這個問題,你可以將元件匯出到它自己的檔案中,然後從另一個檔案匯入該元件

import Profile from './Profile.js';

export default function Gallery() {
  return (
    <section>
      <h1>Amazing scientists</h1>
      <Profile />
      <Profile />
      <Profile />
    </section>
  );
}

準備好學習這個主題了嗎?

閱讀匯入和匯出元件,學習如何將元件拆分到它們自己的檔案中。

閱讀更多

使用 JSX 撰寫標記

每個 React 元件都是一個 JavaScript 函式,其中可能包含一些 React 渲染到瀏覽器中的標記。React 元件使用一種稱為 JSX 的語法擴充來表示該標記。JSX 看起來很像 HTML,但它更嚴格一些,並且可以顯示動態資訊。

如果我們將現有的 HTML 標記貼到 React 元件中,它並不會總是有效

export default function TodoList() {
  return (
    // This doesn't quite work!
    <h1>Hedy Lamarr's Todos</h1>
    <img
      src="https://i.imgur.com/yXOvdOSs.jpg"
      alt="Hedy Lamarr"
      class="photo"
    >
    <ul>
      <li>Invent new traffic lights
      <li>Rehearse a movie scene
      <li>Improve spectrum technology
    </ul>

如果你有像這樣的現有 HTML,你可以使用轉換器來修復它

export default function TodoList() {
  return (
    <>
      <h1>Hedy Lamarr's Todos</h1>
      <img
        src="https://i.imgur.com/yXOvdOSs.jpg"
        alt="Hedy Lamarr"
        className="photo"
      />
      <ul>
        <li>Invent new traffic lights</li>
        <li>Rehearse a movie scene</li>
        <li>Improve spectrum technology</li>
      </ul>
    </>
  );
}

準備好學習這個主題了嗎?

閱讀使用 JSX 撰寫標記,學習如何撰寫有效的 JSX。

閱讀更多

在 JSX 中使用大括號嵌入 JavaScript

JSX 允許你在 JavaScript 檔案中撰寫類似 HTML 的標記,將渲染邏輯和內容放在同一個地方。有時你會想要新增一些 JavaScript 邏輯或引用該標記內的動態屬性。在這種情況下,你可以在 JSX 中使用大括號來「開啟一個視窗」到 JavaScript

const person = {
  name: 'Gregorio Y. Zara',
  theme: {
    backgroundColor: 'black',
    color: 'pink'
  }
};

export default function TodoList() {
  return (
    <div style={person.theme}>
      <h1>{person.name}'s Todos</h1>
      <img
        className="avatar"
        src="https://i.imgur.com/7vQD0fPs.jpg"
        alt="Gregorio Y. Zara"
      />
      <ul>
        <li>Improve the videophone</li>
        <li>Prepare aeronautics lectures</li>
        <li>Work on the alcohol-fuelled engine</li>
      </ul>
    </div>
  );
}

準備好學習這個主題了嗎?

閱讀在 JSX 中使用大括號嵌入 JavaScript,學習如何從 JSX 存取 JavaScript 資料。

閱讀更多

將屬性傳遞給組件

React 組件使用屬性 (props) 彼此溝通。每個父組件都可以透過提供屬性將一些資訊傳遞給其子組件。屬性可能會讓您聯想到 HTML 屬性,但您可以透過它們傳遞任何 JavaScript 值,包括物件、陣列、函式,甚至 JSX!

import { getImageUrl } from './utils.js'

export default function Profile() {
  return (
    <Card>
      <Avatar
        size={100}
        person={{
          name: 'Katsuko Saruhashi',
          imageId: 'YfeOqp2'
        }}
      />
    </Card>
  );
}

function Avatar({ person, size }) {
  return (
    <img
      className="avatar"
      src={getImageUrl(person)}
      alt={person.name}
      width={size}
      height={size}
    />
  );
}

function Card({ children }) {
  return (
    <div className="card">
      {children}
    </div>
  );
}

準備好學習這個主題了嗎?

閱讀將屬性傳遞給組件,學習如何傳遞和讀取屬性。

閱讀更多

條件式渲染

您的組件通常需要根據不同的條件顯示不同的內容。在 React 中,您可以使用 JavaScript 語法(例如 if 陳述式、&&? : 運算子)來有條件地渲染 JSX。

在此範例中,JavaScript 的 && 運算子用於有條件地渲染核取記號

function Item({ name, isPacked }) {
  return (
    <li className="item">
      {name} {isPacked && '✅'}
    </li>
  );
}

export default function PackingList() {
  return (
    <section>
      <h1>Sally Ride's Packing List</h1>
      <ul>
        <Item
          isPacked={true}
          name="Space suit"
        />
        <Item
          isPacked={true}
          name="Helmet with a golden leaf"
        />
        <Item
          isPacked={false}
          name="Photo of Tam"
        />
      </ul>
    </section>
  );
}

準備好學習這個主題了嗎?

閱讀條件式渲染,學習以不同方式有條件地渲染內容。

閱讀更多

渲染清單

您通常會希望從資料集合中顯示多個類似的組件。您可以將 JavaScript 的 filter()map() 與 React 搭配使用,以過濾和轉換您的資料陣列成組件陣列。

對於每個陣列項目,您需要指定一個 key。通常,您會希望使用資料庫中的 ID 作為 key。鍵讓 React 可以追蹤每個項目在清單中的位置,即使清單發生變化也是如此。

import { people } from './data.js';
import { getImageUrl } from './utils.js';

export default function List() {
  const listItems = people.map(person =>
    <li key={person.id}>
      <img
        src={getImageUrl(person)}
        alt={person.name}
      />
      <p>
        <b>{person.name}:</b>
        {' ' + person.profession + ' '}
        known for {person.accomplishment}
      </p>
    </li>
  );
  return (
    <article>
      <h1>Scientists</h1>
      <ul>{listItems}</ul>
    </article>
  );
}

準備好學習這個主題了嗎?

閱讀渲染清單,學習如何渲染組件清單,以及如何選擇鍵。

閱讀更多

保持組件純粹

有些 JavaScript 函式是*純粹的*。純粹的函式

  • 只管自己的事。 它不會更改在呼叫它之前存在的任何物件或變數。
  • 相同的輸入,相同的輸出。 給定相同的輸入,純粹的函式應始終返回相同的結果。

藉由嚴格地將組件寫成純粹的函式,您可以避免隨著程式碼庫的增長而出現一整類令人困惑的錯誤和不可預測的行為。以下是一個不純粹組件的範例

let guest = 0;

function Cup() {
  // Bad: changing a preexisting variable!
  guest = guest + 1;
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup />
      <Cup />
      <Cup />
    </>
  );
}

您可以透過傳遞屬性而不是修改預先存在的變數,使這個組件變得純粹

function Cup({ guest }) {
  return <h2>Tea cup for guest #{guest}</h2>;
}

export default function TeaSet() {
  return (
    <>
      <Cup guest={1} />
      <Cup guest={2} />
      <Cup guest={3} />
    </>
  );
}

準備好學習這個主題了嗎?

閱讀保持組件純粹,學習如何將組件寫成純粹、可預測的函式。

閱讀更多

您的 UI 作為樹狀結構

React 使用樹狀結構來模擬組件和模組之間的關係。

React 渲染樹是組件之間父子關係的表示。

A tree graph with five nodes, with each node representing a component. The root node is located at the top the tree graph and is labelled 'Root Component'. It has two arrows extending down to two nodes labelled 'Component A' and 'Component C'. Each of the arrows is labelled with 'renders'. 'Component A' has a single 'renders' arrow to a node labelled 'Component B'. 'Component C' has a single 'renders' arrow to a node labelled 'Component D'.
A tree graph with five nodes, with each node representing a component. The root node is located at the top the tree graph and is labelled 'Root Component'. It has two arrows extending down to two nodes labelled 'Component A' and 'Component C'. Each of the arrows is labelled with 'renders'. 'Component A' has a single 'renders' arrow to a node labelled 'Component B'. 'Component C' has a single 'renders' arrow to a node labelled 'Component D'.

一個 React 渲染樹的範例。

靠近樹狀結構頂部、靠近根組件的組件被視為頂層組件。沒有子組件的組件是葉子組件。這種組件分類有助於理解資料流程和渲染效能。

模擬 JavaScript 模組之間的關係是理解應用程式的另一種有用方法。我們將其稱為模組依賴樹。

A tree graph with five nodes. Each node represents a JavaScript module. The top-most node is labelled 'RootModule.js'. It has three arrows extending to the nodes: 'ModuleA.js', 'ModuleB.js', and 'ModuleC.js'. Each arrow is labelled as 'imports'. 'ModuleC.js' node has a single 'imports' arrow that points to a node labelled 'ModuleD.js'.
A tree graph with five nodes. Each node represents a JavaScript module. The top-most node is labelled 'RootModule.js'. It has three arrows extending to the nodes: 'ModuleA.js', 'ModuleB.js', and 'ModuleC.js'. Each arrow is labelled as 'imports'. 'ModuleC.js' node has a single 'imports' arrow that points to a node labelled 'ModuleD.js'.

一個模組依賴樹的範例。

建置工具通常使用依賴樹來捆綁所有相關的 JavaScript 程式碼,供客戶端下載和渲染。大型的捆綁包大小會降低 React 應用程式的使用者體驗。瞭解模組依賴樹有助於除錯此類問題。

準備好學習這個主題了嗎?

閱讀您的 UI 作為樹狀結構,學習如何建立 React 應用程式的渲染樹和模組依賴樹,以及它們如何作為改進使用者體驗和效能的有用心智模型。

閱讀更多

接下來是什麼?

前往 您的第一個組件 開始逐頁閱讀本章!

或者,如果您已經熟悉這些主題,為什麼不閱讀關於 新增互動性 的內容?