# React 概述
<center><img src="https://miro.medium.com/v2/resize:fit:1400/0*y6IcBe5J1AdALzXw.png" /></center>
## 前言
在我們今天的主角 React 登場之前,我們先來聊聊一個更根本的概念:「什麼是前端框架?」
在網頁開發的早期,我們就是用這三樣東西「純手工」打造網頁。
* 用 HTML 刻出骨架。
* 用 CSS 加上美觀的樣式。
* 用 JavaScript (我們常說的 Vanilla JS) 來增加互動,像是「點擊按鈕後,跳出一個視窗」。
這在製作簡單的靜態網站時,完全沒問題。
但是,當網頁應用 (Web App) 變得越來越複雜——想想看 Gmail、Google Maps 或是 Facebook,我們開始開發這類網站時將會遇到巨大的麻煩。
想像一下,你正在用純 JavaScript 開發一個像 Facebook 這樣的動態牆:
* 有幾十個「讚」按鈕,每個都要獨立計數。
* 有人留言,列表要「即時」更新,不用重新整理頁面。
* 右上角的「通知」圖示要顯示未讀訊息的「紅點」。

如果你真的利用純 JavaScript 去開發邏輯部分的話,你很快就會發現,你的 JavaScript 程式碼變得一團混亂:
* DOM 操作地獄: 你會寫滿 <code>document.getElementById</code> 和 <code>.addEventListener</code>。
* 狀態管理混亂: 你的資料(例如:按讚數、留言列表)散落在各處。當資料更新時,你必須「手動」記得去更新畫面上 所有 相關的地方。
* 難以維護: 程式碼牽一髮動全身,修改一個小功能,可能導致另一個地方壞掉。
**而以上就是「前端框架」誕生的原因。**
前端框架幫我們**能夠更有結構化、更方便的去開發網站**。
主流的前端框架有分很多種像是 React、Vue、Angular 等等,那麼我們這次的主角就是 **React**。
## 核心概念 (一) - 元件化 (Component-based)
### 甚麼是元件 (Component)
就像是你玩樂高積木一樣,能夠把複雜的 UI 變成一個可以重複使用的積木。例如: <code>NavBar</code>、<code>Card</code>、<code>Button</code>。
### JSX 語法擴充 - 寫在 JavaScript 中的「HTML」
傳統的 HTML 與 Javascript 是不能夠寫在一起的,所以每次當你要去操作網頁中的某個物件的時候,每次都要手動操作 DOM (<code>document.getElementById...</code>),如果你做的網頁很大,那麼這會變得非常的麻煩。所以有了 JSX,我們網頁的 UI 結構和邏輯(例如 map 產生列表)可以寫在一起,非常直觀。
### Function Component (函數式元件)
**Function Component 就是一個普通的 JavaScript 函式 (Function)。**
它接受一個名為 `props` (屬性) 的物件作為參數,然後**回傳 (return)** 描述你想在螢幕上看到什麼的 **React 元素 (通常是 JSX)**。
### Props (屬性):元件間的溝通
* 概念: 父母 (Parent Component) 傳遞資料給小孩 (Child Component) 的方式。
* 特性: 單向資料流 (One-Way Data Flow)、唯讀 (Read-Only)。
* 範例: 定義一個 <code>Button</code> 組件, 假設<code><Button text="點我" color="blue" /></code>,那麼其中 <code>text</code> 與 <code>color</code> 為 <code>Button</code> 這個元件的 Props
### 範例 - 介紹卡片 (虛擬碼)
#### 不使用 React
```html=
<body>
<h1>我們的團隊</h1>
<div class="card">
<img src="https://via.placeholder.com/150" alt="用戶頭像">
<h3>Alice</h3>
<p>我是一個前端工程師。</p>
</div>
<div class="card">
<img src="https://via.placeholder.com/150" alt="用戶頭像">
<h3>Bob</h3>
<p>我是一個後端工程師。</p>
</div>
<div class="card">
<img src="https://via.placeholder.com/150" alt="用戶頭像">
<h3>Stacy</h3>
<p>我是一個 PM。</p>
</div>
</body>
```
#### 使用 React
<code>ProfileCard.js</code>
```javascript=
import React from 'react';
// 這就是一個「元件」
// 它是一個函式,會接收一個 props 物件 (裡面放著外面傳進來的資料)
// 然後回傳它該長什麼樣子的 JSX
function ProfileCard(props) {
return (
<div className="card">
<img src={props.imageUrl} alt="用戶頭像" />
<h3>{props.name}</h3>
<p>{props.description}</p>
</div>
);
}
export default ProfileCard;
```
<code>App.js</code>
```javascript=
import React from 'react';
import ProfileCard from './ProfileCard'; // 載入我們剛剛做的卡片元件
import './styles.css'; // 假設 CSS 樣式跟 HTML 範例一樣
// 這是主要的 App 元件
function App() {
const profileData = [
{
name: "Alice",
description:"我是一個前端工程師",
imageUrl: "https://via.placeholder.com/150"
},
{
name: "Bob",
description:"我是一個後端工程師",
imageUrl: "https://via.placeholder.com/150"
},
{
name: "Stacy",
description:"我是一個 PM",
imageUrl: "https://via.placeholder.com/150"
}
]
return (
<div>
<h1>我們的團隊</h1>
{profileData.map(profile => (
<ProfileCard
key={profile.name}
name={profile.name}
description={profile.description}
imageUrl={profile.imageUrl}
/>
))}
</div>
);
}
export default App;
```
## 核心概念 (二) - 狀態與生命週期 (State & Hooks)
### State (狀態):讓元件擁有自己的「記憶體」
* 概念: 讓元件「記住」事情的機制(例如:計數器、輸入框的文字)。
* 關鍵: 當 State 改變時,React 會自動重新渲染 (Re-render) 元件。 (這是 React 的魔法核心!)
那我們要怎麼去讓元件自己的狀態呢 ? 這時候 Hooks 登場了
### Hooks 登場:讓函式元件 (Functional Component) 擁有超能力
#### useState():
* 功能:讓元件能夠有自己的狀態 (state)
* 範例:以下是一個簡單的「計數器」按鈕,展示 [count, setCount] 的用法。
```javascript=
import React from "react";
export default function CustomizedButton() {
const [count, setCount] = React.useState(0)
const clickHandler = () => {
setCount(count + 1);
}
return (
<div>
<h1>This Button has State</h1>
<button onClick={clickHandler}>Click Count : {count}</button>
</div>
)
}
```
#### useEffect():
* 功能:處理「副作用」(Side Effects)。
* 什麼是副作用? 就是任何「渲染畫面」以外的事情。
* 常見的副作用:
* 向資料庫讀取資料 (Data Fetching)。
* 設定計時器 (<code>setTimeout</code>)。
* 手動操作 DOM。
* 總之,<code>useEffect</code>就是將這些 **「與渲染無關,但又必須執行的操作」** 從純粹的渲染邏輯中分離出來,並允許你在組件的生命週期(掛載、更新、卸載)中,以可預測且受控的方式執行它們。
* 範例:以下是一個簡單的 data fetch 模擬並且記錄 data fetching 的次數。
```javascript=
import React from "react";
export default function CustomizedButton() {
const [count, setCount] = React.useState(0)
const [toggle, setToggle] = React.useState(false);
const clickHandler = () => {
setCount(count + 1)
setToggle(!toggle);
}
// Mocking data fetching with useEffect
React.useEffect(() => {
let message = "Data fetching...";
console.log(message);
const timer = setTimeout(() => {
message = "Fetching complete!";
console.log(message);
}, 2000);
return () => {
clearTimeout(timer);
}
}, [toggle]);
return (
<div>
<h1>This Button has State</h1>
<button onClick={clickHandler} className="custom-btn">Fetch Count : {count}</button>
</div>
)
}
```
## 核心概念 (三) - React 的「快」,為什麼?
* Virtual DOM (虛擬 DOM)
* 問題: 頻繁且大量地直接操作「真實 DOM」非常昂貴(效能差)。
* React 的解法:
* 在 JavaScript 記憶體中,建立一個「虛擬」的 DOM 結構 (V-DOM)。
* 當 State 改變時,React 建立一個 新的 V-DOM。
* Diffing Algorithm (差異比對): React 快速比對「舊 V-DOM」和「新 V-DOM」的差別。
* Reconciliation (調節): 只把 真正有改變 的部分,一次性地更新到「真實 DOM」上。
* 比喻: 你不是重蓋整棟房子(**操作 Real-DOM**),你只是找到哪片油漆剝落了,然後只補那塊漆(**操作 Virtual DOM**)。
---
文件參考:https://react.dev/reference/react