第五章:新手必學!React Hooks 與狀態管理 (什麼是 State?)
在上一章我們把網站部署出去了,但目前的網站只能「看」,不能「互動」。 如果你想要做一個「點擊按鈕,數字會增加」或是「打開/關閉彈出視窗」的功能,你就必須學會 React 的核心魔法:Hooks (狀態鉤子)。
過去的前端工程師為了學會狀態管理,必須啃讀厚厚的官方文件,還要搞懂 Class Component 的生命週期。但在 Vibe Coding 的世界裡,你只要懂「觀念」,剩下的複雜程式碼都可以交給 AI。本章我們將以最白話的方式,帶你徹底征服 React 最重要的兩個 Hooks。
🧠 觀念釐清:什麼是 State (狀態)?
想像一下,你的網頁是一個「數位看板」。 如果看板上寫著「目前預約人數:5 人」,這個「5」就是一個 State (狀態)。
在傳統的網頁 (Vanilla JS 或 jQuery) 裡,如果你想把 5 變成 6,你必須自己去操控 DOM:
- 找出畫面上的那個
<span>標籤。 - 把它原本的數字擦掉。
- 把新的數字寫上去。 這就像是你親自拿著抹布跟麥克筆在更新實體看板,非常費力。
但在 React 裡,你只要告訴系統:「把我的大腦裡的狀態加 1」,React 就會**自動幫你把畫面上所有用到這個狀態的地方,瞬間更新!**這被稱為「資料驅動視圖 (Data-driven View)」。
而用來記住這個狀態的工具,就叫做 useState。
🎣 實戰演練:useState 預約天數計算機
我們來實作一個商業上極度常見的功能:「購物車數量增減」或是「預約天數計算機」。
🔥【Vibe Prompt 實戰咒語】 我是一個 React 新手。請幫我在
src/components/中寫一個DaysCalculator.tsx元件。 需求如下:
- 使用
useState來記錄「預約天數 (days)」,預設值為 1。- 畫面上有一個減號按鈕、一個顯示天數的文字、和一個加號按鈕。請將它們水平排列。
- 邏輯限制:天數最少不能低於 1 天,最多不能超過 14 天 (如果達到極限,請把按鈕設為 disabled 並變成灰色)。
- 動態計價:下方動態顯示「總金額」,假設一天是 NT$ 1,200,請自動相乘並加上千分位逗號。
- UI 設計:請用 Tailwind CSS 設計出具有現代感、帶有輕微陰影的 Glassmorphism (玻璃擬物化) 卡片樣式。
- 請在程式碼中加上超詳細的中文註解,向我解釋
useState是怎麼運作的。
AI 會生成一個超美的計數器。仔細看它生成的這行核心程式碼:
const [days, setDays] = useState(1);
這就是 React 最經典的語法,它回傳了一個陣列,裡面有兩個東西:
days:用來讀取現在是幾天(你的變數)。setDays:用來改變天數的遙控器(一個函數)。當你的加號按鈕被點擊時,執行setDays(days + 1),畫面就會瞬間重新渲染!
👁️ 觀念釐清:什麼是 useEffect (副作用)?
有時候,你希望「當某件事情發生的時候,自動去做另一件事」。 例如:
- 當網頁剛載入時,去跟後端要最新的商品資料。
- 當預約天數改變時,把這個天數存進瀏覽器的
localStorage裡面。 - 當使用者關閉視窗時,停止計時器。
這種「牽一髮而動全身」或「與外部系統互動」的行為,在 React 裡稱為 Effect (副作用),我們使用 useEffect 來處理。
🔥【Vibe Prompt 實戰咒語 (接續上一步)】 請修改剛剛的
DaysCalculator.tsx。
- 我想要加入
useEffect:當「預約天數 (days)」發生改變時,在 Console (開發者工具) 裡面印出 "使用者將天數更改為 X 天"。- 請再加上一個
useEffect,在元件「第一次載入時」,自動彈出一個歡迎訊息的 toast 提示。- 請用註解向我這個新手解釋
useEffect的 Dependency Array (依賴陣列) 是什麼意思。
AI 會幫你加上這段關鍵程式碼:
// 範例一:依賴陣列裡有東西
useEffect(() => {
console.log(`使用者將天數更改為 ${days} 天`);
}, [days]); // <- 這個中括號就是 Dependency Array
// 範例二:依賴陣列是空的
useEffect(() => {
toast.success("歡迎來到預約系統!");
}, []); // <- 空陣列代表「只在第一次載入時執行一次」
- 第一個例子中括號裡面放
days,意思是:只有當 days 改變時,才執行裡面的程式碼。 - 第二個例子中括號是空的
[],代表沒有任何依賴,所以只在網頁剛載入時執行一次 (這非常適合用來串接 API 撈資料!)。
⚠️ [常見地雷區] 無限迴圈 (Infinite Loop)
新手在使用 useEffect 時,最容易引發足以讓電腦當機的「無限迴圈」地獄。
錯誤示範:
const [count, setCount] = useState(0);
useEffect(() => {
setCount(count + 1); // 錯誤!這會導致無限迴圈
}, [count]);
發生什麼事?
- 程式看到
count改變了,觸發useEffect。 useEffect裡面又去執行setCount(count + 1)。count又改變了,再次觸發useEffect... 就這樣一秒鐘執行一萬次,直到你的瀏覽器直接死當崩潰。
Vibe Coder 解法:當你的瀏覽器卡住不動時,這幾乎 100% 是無限迴圈惹的禍。請直接圈選你的 useEffect 程式碼問 AI:「我的網頁卡死了,這裡是不是發生了無限迴圈?請幫我修復依賴陣列的邏輯。」
💼 [商業應用場景] 電商網站的「購物車」與「最近瀏覽」
學會了 useState 與 useEffect,你就等於掌握了電商網站的核心印鈔機。
應用 1:全站購物車狀態 (結合 Context/Zustand)
你可以用狀態管理來記住使用者把哪些商品丟進了購物車。當他點擊「加入購物車」(setCartItems),右上角的購物車圖示數字瞬間更新。這種絲滑的體驗能大幅提升轉換率。
應用 2:「最近瀏覽商品」的追蹤
利用 useEffect,當使用者點進某個商品頁面 (元件載入時),立刻觸發一個 API 將這個商品 ID 寫入資料庫的「最近瀏覽」清單中。
有了這份資料,你就可以在首頁顯示「為您推薦 (根據您最近的瀏覽)」,這項功能在業界被證明能提升至少 15% 的客單價!
下一章,我們要把這兩個基礎觀念結合起來,挑戰網頁開發最複雜、但也最值錢的一環:實作 Supabase 會員登入介面!