第四章:讓前端活起來!API 串接、Axios 與非同步魔法

在上一章,我們用假資料 (Mock Data) 做出了超美的表格與即時搜尋功能。但當你把網頁拿給老闆看時,老闆會問:「為什麼上面的人名都是王小明跟李大華?我今天打卡的紀錄怎麼沒出現?」

沒錯,前端的資料是寫死在程式碼裡的,它不知道現實世界發生了什麼事。 真實世界中,前端網頁必須主動去向「後端伺服器 (例如我們之前寫的 FastAPI)」請求最新資料,這個前端與後端溝通的橋樑,就叫做 API (應用程式介面)

🎯 本章目標

  1. 聽懂前端與後端溝通的底層邏輯:什麼是 HTTP Request?什麼是 API?
  2. 認識業界最強的 HTTP 客戶端套件:axios
  3. 掌握 React 的 useEffect Hook,實作「網頁一打開就自動去抓資料」的功能。
  4. 處理「載入中 (Loading)」與「錯誤 (Error)」的狀態,這是一個專業前端必備的素養。

📞 什麼是 API?什麼是 Fetch 與 Axios?(白話文圖解)

想像你去一家高級的法式餐廳吃飯:

  • 你 (前端網頁):你看著精美的菜單 (UI 介面),決定要吃什麼。但你不能自己跑進廚房去拿菜。
  • 廚房 (後端資料庫):存放所有生鮮食材 (打卡紀錄) 的地方,並且有廚師 (FastAPI) 負責料理。
  • 服務生 (API):你把點菜單交給服務生,服務生走到廚房把菜端出來給你。這個「點菜」跟「端菜」的動作,就是呼叫 API。

在 JavaScript 裡,呼叫服務生最基本的方法叫做原生函數 fetch()。 但 fetch 寫起來有點囉嗦,處理 JSON 格式還要多轉一手,而且在攔截錯誤時不太聰明。 所以,全球的前端工程師最流行使用一個名為 Axios 的第三方套件,它讓要資料的過程變得極度優雅,且自帶各種強大功能。


🚀 實戰:安裝 Axios 與建立 API 實例 (Instance)

🔥【Vibe Prompt 實戰咒語】 我正在開發 React (Vite) 專案,我需要串接本機的 FastAPI 後端 API。 1. 請給我 npm 安裝 axios 的指令。 2. 業界標準做法通常會把 API 連線設定獨立出來。請幫我在 src/utils/ 建立一個 api.ts 檔案。 3. 在 api.ts 裡面使用 axios.create 建立一個實例 (instance),設定 baseURL 為 'http://localhost:8000/api',並設定 timeout 超時時間為 5000 毫秒。

AI 會教你打開終端機,輸入:

npm install axios

並且生成完美的 API 模組設定檔:

// 📂 src/utils/api.ts
import axios from 'axios';

// 建立 Axios 實例 (Instance)
// 這樣做的好處是:未來你要打 API,不用每次都輸入一長串網址,只要寫 '/punches' 即可!
export const apiClient = axios.create({
  baseURL: 'http://localhost:8000/api', // FastAPI 本機網址
  timeout: 5000, // 如果服務生去廚房超過 5 秒沒回來,就判定為點餐失敗 (超時)
  headers: {
    'Content-Type': 'application/json',
  },
});

⏳ 結合 useEffect:在畫面載入時拿資料

有了 apiClient 之後,我們該在什麼時候去呼叫它呢? 答案是:當這個 Data Table 元件第一次出現在畫面上時! 在 React 中,要控制「第一次出現時做某件事」,我們必須請出強大的 useEffect

🔥【Vibe Prompt 實戰咒語】 請幫我修改之前的 DataTable.tsx,將原本寫死的 mockData 換成真實的 API 呼叫。 1. 請引入剛寫好的 apiClient。 2. 使用 useEffect 在元件【初次掛載 (Mount)】時,打一支 GET /punches 的 API。 3. 請務必處理 3 種狀態:資料 (data)、載入中 (isLoading預設為true)、錯誤訊息 (error)。 4. 在畫面渲染時,如果 isLoading 是 true,請顯示一個轉圈圈或文字「資料載入中...」。如果 error 有值,請顯示紅色的錯誤警告。 5. 當拿到資料時,將後端回傳的陣列 set 進 data state 裡面。

AI 會幫你生出這段極具專業水準的非同步 (Async/Await) 程式碼:

import { useEffect, useState } from 'react';
import { apiClient } from '../utils/api';

export default function DataTable() {
  const [data, setData] = useState([]);
  const [isLoading, setIsLoading] = useState(true);
  const [error, setError] = useState<string | null>(null);

  // 💡 useEffect 加上結尾的空陣列 [],代表這段邏輯只在「畫面第一次出現時」執行一次!
  useEffect(() => {
    const fetchPunchRecords = async () => {
      try {
        setIsLoading(true);
        // 向服務生 (API) 點菜 (請求 /punches 的資料)
        const response = await apiClient.get('/punches');
        
        // 服務生把端回來的菜,放到我們的桌子 (State) 上
        setData(response.data);
      } catch (err) {
        console.error("API 呼叫失敗", err);
        setError("無法取得打卡紀錄,請檢查伺服器是否啟動。");
      } finally {
        // 無論成功或失敗,最後一定要把載入動畫關掉!
        setIsLoading(false);
      }
    };
    
    fetchPunchRecords();
  }, []);

  // 渲染防呆:三元狀態處理
  if (isLoading) return <div className="p-10 text-center animate-pulse">📡 正在從伺服器抓取資料中...</div>;
  if (error) return <div className="p-10 text-center text-red-500 bg-red-50 rounded-lg">❌ {error}</div>;

  return (
    // ... 在這裡渲染你原本精美的表格,並傳入真實的 data ...
    <div>
        {/* 表格 UI 省略... */}
    </div>
  );
}

💼 [商業應用場景] 為什麼 Skeleton (骨架屏) 這麼重要?

在上面的實作中,我們加入了 isLoading 的狀態。如果你把這個系統賣給大企業,這點極其重要。 當網頁在等待後端資料的這 0.5 秒鐘內,如果畫面上什麼都沒有,使用者會以為網站當機了,他會瘋狂地點擊重新整理按鈕,這會產生兩倍的 API 請求,最終把你的伺服器塞爆。

這被稱為 User Perceived Latency (使用者感知延遲)。 身為一個專業的開發者,你可以在 Prompt 裡面跟 AI 說:「在 isLoading 的時候,請給我一個 Tailwind 寫的 Skeleton (骨架屏) 特效」。讓畫面上出現幾個灰色、正在閃爍的假區塊。 使用者看著閃爍的區塊,會覺得「系統正在努力運作」,他們的耐心會從 0.5 秒延長到 3 秒。這個小小的 UI 細節,就是菜鳥與資深工程師的巨大分水嶺!

✅ 本章小結

你成功學會了前端工程師每天都在做的核心工作:向後端要資料,並優雅地處理等待與報錯,最後把真實資料顯示在畫面上!

但是,當你第一次滿懷期待地跑這段程式碼,看著 Chrome 瀏覽器時,你通常等不到資料,反而會遇到一個前端開發者一輩子的宿敵:「CORS 跨域阻擋錯誤」。 別怕!所有的工程師都經歷過這個崩潰時刻。下一章,我們將用最白話的方式,為你解開 CORS 的秘密,並教你如何用 Prompt 一秒鐘解決它!

解鎖完整教學內容

本章為付費內容。加入專案即可解鎖超過 5000 字的深度解析,包含 10 個以上神級 Prompt 與真實 Source Code 範例!