【Vibe Coder 的 React 教學】#02 JSX 與元件基礎:讓 AI 幫你寫出第一個元件

測驗:JSX 與元件基礎

共 5 題,點選答案後會立即顯示結果

1. 在 JSX 中,為什麼要用 className 而不是 class

  • A. 因為 className 比較短
  • B. 因為 class 是 JavaScript 的保留字
  • C. 因為 React 團隊覺得這樣比較好看
  • D. 因為 HTML5 規範改了

2. 以下哪個是 React 元件名稱的正確命名方式?

  • A. function userCard() { ... }
  • B. function user_card() { ... }
  • C. function UserCard() { ... }
  • D. function USER_CARD() { ... }

3. 在 JSX 中,{} 大括號的作用是什麼?

  • A. 用來包裹 CSS 樣式
  • B. 用來在 JSX 中執行 JavaScript 表達式
  • C. 用來定義元件的邊界
  • D. 用來建立 HTML 註解

4. 以下程式碼有什麼問題?

function Card() { return ( <h1>標題</h1> <p>內容</p> ); }
  • A. JSX 只能回傳一個根元素,需要用 div 或 Fragment 包起來
  • B. 元件名稱 Card 不正確
  • C. return 關鍵字使用錯誤
  • D. h1 和 p 標籤不能同時使用

5. 關於 export default 和具名 export,以下敘述何者正確?

  • A. 一個檔案可以有多個 export default
  • B. 使用具名 export 導入時不需要大括號
  • C. export default 導出的元件名稱必須與檔案名相同
  • D. export default 導入時可以任意取名,具名 export 導入時名稱要對應

一句話說明

JSX 讓你在 JavaScript 裡寫 HTML,元件讓你把畫面拆成可重複使用的小塊。


本篇學習目標

讀完本篇後,你能夠:

  • 理解 JSX 語法與 HTML 的差異
  • 建立 Function Component 並正確導出
  • 使用 AI 生成元件並理解其結構
  • 組合多個元件建構頁面

JSX 是什麼?

最小範例

const element = <h1>Hello, World!</h1>;
Code language: JavaScript (javascript)

一句話:JSX 就是「可以寫在 JavaScript 裡的 HTML」。

逐行翻譯

const element = <h1>Hello, World!</h1>;
//    ↑ 宣告變數   ↑ 這看起來像 HTML,但其實是 JSX
Code language: JavaScript (javascript)

React 會把 JSX 轉換成 JavaScript:

// JSX 寫法
const element = <h1>Hello</h1>;

// React 實際執行的東西(你不用自己寫這個)
const element = React.createElement('h1', null, 'Hello');
Code language: JavaScript (javascript)

Vibe Coder 知道就好:你只需要寫 JSX,背後的轉換 React 會自動處理。


JSX 與 HTML 的差異

這是 AI 生成的 React 代碼時,你最常看到和 HTML 不一樣的地方:

差異對照表

HTML 寫法 JSX 寫法 為什麼不同
class="btn" className="btn" class 是 JS 保留字
for="email" htmlFor="email" for 是 JS 保留字
onclick="..." onClick={...} 事件用 camelCase
style="color: red" style={{ color: 'red' }} style 要用物件
<img> <img /> 所有標籤都要關閉

最常見的三個差異

1. className 取代 class

// HTML
<div class="container">內容</div>

// JSX - 用 className
<div className="container">內容</div>
Code language: HTML, XML (xml)

2. {} 大括號放 JavaScript

const name = "小明";
const age = 25;

// {} 裡面放任何 JavaScript 表達式
<div>
  <p>名字:{name}</p>
  <p>年齡:{age}</p>
  <p>明年:{age + 1}</p>
  <p>現在時間:{new Date().toLocaleString()}</p>
</div>
Code language: JavaScript (javascript)

一句話:看到 {} 就是「這裡要執行 JavaScript」。

3. style 要用物件

// HTML
<p style="color: red; font-size: 20px">文字</p>

// JSX - 用雙大括號(外層是「這是 JS」,內層是「物件」)
<p style={{ color: 'red', fontSize: '20px' }}>文字</p>
//         ↑↑ 第一個 { 是「放 JS」
//            ↑ 第二個 { 是「物件開始」
Code language: PHP (php)

注意:CSS 屬性名稱改成 camelCase(font-sizefontSize


Function Component:你的第一個元件

最小範例

function Greeting() {
  return <h1>Hello!</h1>;
}
Code language: JavaScript (javascript)

一句話:元件就是「回傳 JSX 的函式」。

元件的三個規則

// 規則 1:名稱首字母大寫
function Greeting() {     // ✅ Greeting 首字母大寫
  // 規則 2:一定要 return 一個東西
  return (
    // 規則 3:只能回傳「一個」根元素
    <div>
      <h1>Hello!</h1>
      <p>歡迎光臨</p>
    </div>
  );
}
Code language: JavaScript (javascript)

為什麼要首字母大寫?

// 小寫 = HTML 標籤
<div>這是 HTML 的 div</div>

// 大寫 = 你的元件
<Greeting />   // 這會執行 Greeting 函式
Code language: HTML, XML (xml)

一句話:React 靠大小寫分辨「這是 HTML 標籤還是自訂元件」。

常見變化:箭頭函式寫法

AI 可能用這兩種寫法,都是一樣的:

// 寫法 1:一般函式
function Greeting() {
  return <h1>Hello!</h1>;
}

// 寫法 2:箭頭函式
const Greeting = () => {
  return <h1>Hello!</h1>;
};

// 寫法 3:箭頭函式簡寫(省略 return)
const Greeting = () => <h1>Hello!</h1>;
Code language: JavaScript (javascript)

翻譯:三種寫法效果完全一樣,選你看得順眼的。


元件的導入與導出

最小範例

// Greeting.jsx(元件檔案)
export default function Greeting() {
  return <h1>Hello!</h1>;
}

// App.jsx(使用元件的檔案)
import Greeting from './Greeting';

function App() {
  return <Greeting />;
}
Code language: JavaScript (javascript)

導出的兩種方式

// 方式 1:export default(一個檔案只能有一個)
export default function Greeting() { ... }

// 在其他檔案導入
import Greeting from './Greeting';          // 名字可以隨便取
import MyGreeting from './Greeting';        // 這樣也可以

// 方式 2:具名 export(一個檔案可以有多個)
export function Greeting() { ... }
export function Farewell() { ... }

// 在其他檔案導入
import { Greeting, Farewell } from './components';  // 名字要對
Code language: JavaScript (javascript)

Vibe Coder 檢查點

看到 import/export 時確認:

  • [ ] 用 default 導出的,import 時不用 {}
  • [ ] 具名導出的,import 時要用 {}
  • [ ] 路徑有沒有 ./(相對路徑要加)

元件組合:把大元件拆成小元件

為什麼要拆?

// 不好:全部寫在一起
function Page() {
  return (
    <div>
      <header>
        <h1>網站標題</h1>
        <nav>選單...</nav>
      </header>
      <main>
        <article>文章內容...</article>
        <aside>側邊欄...</aside>
      </main>
      <footer>頁尾...</footer>
    </div>
  );
}

// 好:拆成小元件
function Page() {
  return (
    <div>
      <Header />
      <Main />
      <Footer />
    </div>
  );
}
Code language: JavaScript (javascript)

一句話:拆成小元件,每個元件只做一件事。

實際範例:使用者卡片

// UserCard.jsx
function UserCard() {
  return (
    <div className="card">
      <Avatar />
      <UserInfo />
    </div>
  );
}

function Avatar() {
  return <img src="/avatar.png" alt="頭像" />;
}

function UserInfo() {
  return (
    <div>
      <h2>小明</h2>
      <p>前端工程師</p>
    </div>
  );
}

export default UserCard;
Code language: JavaScript (javascript)

在頁面中使用多個元件

// App.jsx
import UserCard from './UserCard';

function App() {
  return (
    <div>
      <h1>團隊成員</h1>
      <UserCard />
      <UserCard />
      <UserCard />
    </div>
  );
}
Code language: JavaScript (javascript)

Vibe Coding 技巧:讓 AI 幫你生成元件

好用的 Prompt 範本

1. 生成新元件

幫我建立一個 React 元件叫 ProductCard,
顯示商品圖片、名稱、價格,
使用 Tailwind CSS。

2. 把 HTML 轉成 React 元件

把這段 HTML 轉成 React Function Component:
[貼上你的 HTML]

記得:
- class 改成 className
- 事件處理用 camelCase
Code language: JavaScript (javascript)

3. 拆分大元件

這個元件太大了,幫我拆成更小的元件:
[貼上現有元件]

每個子元件放在同一個檔案,並在最後導出主元件。
Code language: CSS (css)

檢查 AI 生成的元件

看到 AI 生成的元件時確認:

  • [ ] 元件名稱有沒有首字母大寫?
  • [ ] 有沒有 export(default 或具名)?
  • [ ] class 有沒有改成 className
  • [ ] 事件如 onclick 有沒有改成 onClick
  • [ ] JSX 有沒有只回傳一個根元素?

常見錯誤與解法

錯誤 1:忘記首字母大寫

// 錯誤 - 小寫被當成 HTML 標籤
function greeting() {
  return <h1>Hello</h1>;
}
<greeting />  // ❌ 不會正常運作

// 正確
function Greeting() {
  return <h1>Hello</h1>;
}
<Greeting />  // ✅
Code language: JavaScript (javascript)

錯誤 2:回傳多個根元素

// 錯誤 - 不能回傳兩個並列的元素
function Card() {
  return (
    <h1>標題</h1>
    <p>內容</p>
  );  // ❌ 語法錯誤
}

// 正確 - 用一個 div 包起來
function Card() {
  return (
    <div>
      <h1>標題</h1>
      <p>內容</p>
    </div>
  );  // ✅
}

// 或用 Fragment(不會產生額外的 div)
function Card() {
  return (
    <>
      <h1>標題</h1>
      <p>內容</p>
    </>
  );  // ✅ <> 是 Fragment 的簡寫
}
Code language: JavaScript (javascript)

錯誤 3:忘記關閉標籤

// 錯誤
<img src="photo.jpg">
<input type="text">
<br>

// 正確 - JSX 所有標籤都要關閉
<img src="photo.jpg" />
<input type="text" />
<br />
Code language: HTML, XML (xml)

本篇重點整理

必看懂(會一直出現)

你會看到 意思
<Component /> 使用名為 Component 的元件
className="..." 設定 CSS class
{變數} 在 JSX 裡放 JavaScript
export default 導出這個檔案的主元件
import X from './X' 從檔案導入元件

知道就好(遇到再查)

  • <></> Fragment:不想多一層 div 時用
  • dangerouslySetInnerHTML:插入原始 HTML(很少用)
  • React.createElement:JSX 背後的原理

下一篇預告

學會建立元件後,接下來要學「怎麼讓元件接收資料」。下一篇將介紹 Props:元件的參數傳遞,讓你的元件變得更靈活、更可重複使用。

進階測驗:JSX 與元件基礎

測驗目標:驗證你是否能在實際情境中應用所學。
共 5 題,包含情境題與錯誤診斷題。

1. 你正在把一段 HTML 轉換成 React 元件,以下是原始 HTML: 情境題

<div class=”card”> <label for=”email”>電子郵件</label> <input type=”email” onclick=”validate()”> </div>

轉換成 JSX 後,哪些地方需要修改?

  • A. 只需要把 class 改成 className
  • B. 把 class 改成 classNamefor 改成 htmlFor
  • C. 把 class 改成 classNamefor 改成 htmlForonclick 改成 onClick<input> 要自閉合
  • D. 只需要把 <input> 標籤加上閉合斜線

2. 你想在頁面上顯示使用者的年齡和明年的年齡,以下哪種寫法正確? 情境題

const age = 25;
  • A. <p>年齡:age,明年:age + 1</p>
  • B. <p>年齡:{age},明年:{age + 1}</p>
  • C. <p>年齡:${age},明年:${age + 1}</p>
  • D. <p>年齡:(age),明年:(age + 1)</p>

3. 你建立了一個 Header 元件,想在 App.jsx 中使用它。Header.jsx 的內容如下: 情境題

// Header.jsx export default function Header() { return <header>網站標題</header>; }

在 App.jsx 中,哪種導入方式是正確的?

  • A. import { Header } from './Header';
  • B. import * as Header from './Header';
  • C. require('./Header');
  • D. import Header from './Header';

4. 小明的 React 元件無法正常顯示,以下是他的程式碼: 錯誤診斷

function greeting() { return <h1>Hello!</h1>; } // 在 App 中使用 function App() { return <greeting />; }

最可能的問題是什麼?

  • A. return 語句缺少括號
  • B. 元件名稱 greeting 首字母沒有大寫,被 React 當成 HTML 標籤處理
  • C. 沒有使用 export 導出元件
  • D. JSX 語法錯誤,h1 標籤不正確

5. 以下程式碼執行時出現錯誤,問題出在哪裡? 錯誤診斷

function ProfileCard() { return ( <img src=”avatar.jpg”> <h2>小明</h2> <p style=”color: blue; font-size: 14px”>工程師</p> ); }
  • A. img 標籤的 src 路徑錯誤
  • B. h2 標籤不能放在這個位置
  • C. 只有 style 屬性寫法錯誤,應該用雙大括號和 camelCase
  • D. 有多個錯誤:img 沒有自閉合、回傳多個根元素、style 應該用物件格式

發佈留言

發佈留言必須填寫的電子郵件地址不會公開。 必填欄位標示為 *