Skip to main content

畫面組裝的藍圖:component 初探

什麼是 Component

Component(元件) 是 React 的核心概念之一,它是構成使用者介面(UI)的獨立、可重複使用的程式碼區塊。你可以把 Component 想像成一個個小積木,每個 Component 負責畫面的一部分(例如按鈕、表單、導覽列等),這些小積木可以組合起來形成完整的網頁。

在 React 中,Component 可以是:

  • 函數式元件(Function Component):使用 JavaScript 函數定義,現在是 React 的主流方式。

  • 類元件(Class Component):使用 ES6 的 Class 語法,較舊的方式,現在較少使用。

範例: 假設你要製作一個顯示「Hello, World!」的元件:

// 函數式元件
function Greeting() {
return <h1>Hello, World!</h1>;
}

這個 Greeting 元件是一個簡單的函數,返回 JSX(一種看起來像 HTML 的語法,用來描述 UI)。React 會將這個元件渲染到畫面上。


定義 Component

在 React 中,定義 Component 的方式主要使用 函數式元件。以下是定義元件的步驟:

  1. 建立一個函數:函數名稱通常以大寫字母開頭。

  2. 返回 JSX:函數必須返回 JSX,用來描述元件的畫面結構。

  3. 可選:使用 Props:元件可以接受外部傳入的參數(Props),讓元件更靈活。

完整範例: 假設你要定義一個顯示使用者名稱的元件:

// 定義一個函數式元件
function UserProfile() {
return (
<div>
<h2>使用者資料</h2>
<p>姓名:小明</p>
</div>
);
}

步驟解析

  • 函數名稱 UserProfile 是大寫開頭。

  • 返回的 JSX 包含一個 <div>,裡面有標題和段落。

  • 這個元件目前是靜態的,之後會學到如何用 Props 動態傳入資料。


呼叫 Component

定義好 Component 後,你需要在其他地方「呼叫」它來使用。React 的 Component 可以像 HTML 標籤一樣被使用,只不過是用你定義的元件名稱。

範例: 假設你已經定義了 UserProfile 元件,現在要在主應用程式中呼叫它:

import React from "react";
import ReactDOM from "react-dom/client";

// 定義元件
function UserProfile() {
return (
<div>
<h2>使用者資料</h2>
<p>姓名:小明</p>
</div>
);
}

// 主應用程式
function App() {
return (
<div>
<h1>我的網站</h1>
<UserProfile /> {/* 呼叫元件 */}
</div>
);
}

// 渲染到畫面
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<App />);

步驟解析

  1. 在 App 元件中,使用 <UserProfile /> 來呼叫 UserProfile 元件,就像使用 HTML 標籤一樣。

  2. 最終,React 會將 UserProfile 的內容渲染到畫面,顯示「使用者資料」和「姓名:小明」。


Import 與 Export Component

在實際專案中,元件通常會寫在不同的檔案中,這樣程式碼更模組化。你需要使用 ES6 的模組系統 來匯入(Import)和匯出(Export)元件。

範例: 假設你有兩個檔案:UserProfile.js 和 App.js。

  1. UserProfile.js(定義並匯出元件):

    // UserProfile.js
    function UserProfile() {
    return (
    <div>
    <h2>使用者資料</h2>
    <p>姓名:小明</p>
    </div>
    );
    }

    export default UserProfile; // 匯出元件
  2. App.js(匯入並使用元件):

    // App.js
    import React from "react";
    import UserProfile from "./UserProfile"; // 匯入元件

    function App() {
    return (
    <div>
    <h1>我的網站</h1>
    <UserProfile /> {/* 使用匯入的元件 */}
    </div>
    );
    }

    export default App;
  3. 主程式(index.js)

    // index.js
    import React from "react";
    import ReactDOM from "react-dom/client";
    import App from "./App";

    const root = ReactDOM.createRoot(document.getElementById("root"));
    root.render(<App />);

步驟解析

  • 在 UserProfile.js 中,使用 export default 匯出元件。

  • 在 App.js 中,使用 import 匯入 UserProfile 元件,然後像標籤一樣使用。

  • 檔案結構保持清晰,方便維護和重複使用。


Props

Props(Properties)是用來傳遞資料給元件的機制,讓元件可以動態顯示不同的內容。Props 就像函數的參數,父元件可以傳遞資料給子元件。

範例: 改進之前的 UserProfile 元件,讓它可以接受動態的姓名:

  1. UserProfile.js(接受 Props):

    // UserProfile.js
    function UserProfile(props) {
    return (
    <div>
    <h2>使用者資料</h2>
    <p>姓名:{props.name}</p>
    </div>
    );
    }

    export default UserProfile;
  2. App.js(傳遞 Props):

    // App.js
    import React from "react";
    import UserProfile from "./UserProfile";

    function App() {
    return (
    <div>
    <h1>我的網站</h1>
    <UserProfile name="小明" /> {/* 傳遞 name 屬性 */}
    <UserProfile name="小華" /> {/* 傳遞不同的 name */}
    </div>
    );
    }

    export default App;

步驟解析

  • 在 UserProfile 元件中,props 是一個物件,包含父元件傳來的屬性(例如 name)。

  • 在 App 中,使用 <UserProfile name="小明" /> 傳遞 name 屬性。

  • 畫面會顯示兩個 UserProfile 元件,分別顯示「姓名:小明」和「姓名:小華」。


父 Component 與子 Component

在 React 中,元件之間有層次關係:

  • 父元件:呼叫其他元件的元件(例如 App)。

  • 子元件:被父元件呼叫的元件(例如 UserProfile)。

父元件可以透過 Props 傳遞資料給子元件,子元件則負責渲染這些資料。

範例: 延續上面的程式碼,App 是父元件,UserProfile 是子元件。父元件可以傳遞多個 Props 給子元件:

// UserProfile.js
function UserProfile(props) {
return (
<div>
<h2>使用者資料</h2>
<p>姓名:{props.name}</p>
<p>年齡:{props.age}</p>
</div>
);
}

export default UserProfile;
// App.js
import React from "react";
import UserProfile from "./UserProfile";

function App() {
return (
<div>
<h1>我的網站</h1>
<UserProfile name="小明" age={25} />
<UserProfile name="小華" age={30} />
</div>
);
}

export default App;

步驟解析

  • App 是父元件,透過 Props 傳遞 name 和 age 給子元件 UserProfile。

  • UserProfile 是子元件,接收 Props 並渲染到畫面。

  • 這種結構讓程式碼更有組織性,且子元件可以重複使用。


Component 的 Render 與 Re-render

在 React 中,Render 是指元件根據當前的 Props 和 State(狀態)生成 JSX,並由 React 轉換為真實的 DOM 顯示在畫面上。Re-render 則是當 Props 或 State 改變時,React 會重新執行元件的渲染。

範例: 假設你有一個計數器元件,當按鈕被點擊時,計數器會增加,並觸發 Re-render:

// Counter.js
import React, { useState } from "react";

function Counter() {
const [count, setCount] = useState(0); // 使用 State 來儲存計數

return (
<div>
<p>你點擊了 {count}</p>
<button onClick={() => setCount(count + 1)}>點擊我</button>
</div>
);
}

export default Counter;
// App.js
import React from "react";
import Counter from "./Counter";

function App() {
return (
<div>
<h1>我的網站</h1>
<Counter />
</div>
);
}

export default App;

步驟解析

  1. useState 是 React 的 Hook,用來管理元件的狀態(這裡是 count)。

  2. 當你點擊按鈕,setCount 會更新 count,觸發元件重新渲染(Re-render)。

  3. React 會比較新舊 DOM,只更新改變的部分(例如計數的數字),這是 React 的高效之處。


為什麼 Component 命名中的首字母必須為大寫

在 React 中,元件名稱的首字母必須大寫,這是因為 React 會根據名稱的首字母來區分 React 元件HTML 標籤

  • 小寫名稱:React 認為是原生的 HTML 標籤(例如 <div><p>)。

  • 大寫名稱:React 認為是自訂的元件(例如 <UserProfile>)。

範例: 假設你定義了一個元件,但使用小寫名稱:

// 錯誤範例
function userProfile() {
return <div>錯誤的元件名稱</div>;
}

// 正確範例
function UserProfile() {
return <div>正確的元件名稱</div>;
}

為什麼必須大寫

  • React 使用 JSX 語法,JSX 會將標籤轉換為 JavaScript 程式碼。如果元件名稱是小寫,React 會誤以為它是一個 HTML 標籤,導致無法正確渲染。

  • 大寫名稱讓 React 知道這是一個自訂的元件,會調用對應的函數來渲染。

實務建議

  • 總是用大寫字母開頭命名元件(例如 UserProfile、MyButton)。

  • 檔案名稱通常與元件名稱一致(例如 UserProfile.js)。


總結

透過以上教學,你應該對 React 的 Component 有初步了解:

  • 什麼是 Component:它是 UI 的積木,可重複使用。

  • 定義 Component:使用函數返回 JSX。

  • 呼叫 Component:像 HTML 標籤一樣使用元件。

  • Import 與 Export:用模組系統組織程式碼。

  • Props:讓元件動態顯示資料。

  • 父與子 Component:透過 Props 傳遞資料,形成層次結構。

  • Render 與 Re-render:React 根據 Props 和 State 渲染畫面,狀態改變時重新渲染。

  • 為什麼首字母大寫:React 用來區分元件和 HTML 標籤。

操作建議

  1. 建立一個 React 專案(可以使用 create-react-app 或 Vite)。

  2. 將上述範例程式碼複製到你的專案中,嘗試運行並修改 Props 或 State。

  3. 觀察畫面變化,熟悉元件的渲染行為。