React 技巧:多個 API 同時觸發,只執行一次的處理方法
在前端開發中,經常會遇到「同一個操作或多個元件同時需要呼叫同一個 API」的情境。如果不加控制,可能會造成以下問題:
-
使用者快速點擊按鈕,短時間內重複送出相同請求
-
多個元件同時初始化資料,導致同一份 API 被呼叫多次
-
增加伺服器負擔、浪費網路資源
這篇文章整理兩種常見情境,並提供 React 實作範例,教你如何保證 API 只執行一次。
情境一:同一個使用者動作短時間觸發多次 API
典型情境:按鈕被連點、搜尋框輸入時快速觸發
解決方法:使用旗標 (flag) 或防抖 (debounce) 控制
範例:按鈕連點只呼叫一次 API
import { useState } from "react";
export default function App() {
const [isLoading, setIsLoading] = useState(false);
const handleClick = async () => {
if (isLoading) return; // API 已經在執行就忽略
setIsLoading(true);
try {
const res = await fetch("https://jsonplaceholder.typicode.com/todos/1");
const data = await res.json();
console.log("API 結果:", data);
} finally {
setIsLoading(false);
}
};
return (
<div>
<button onClick={handleClick} disabled={isLoading}>
{isLoading ? "載入中..." : "點我"}
</button>
</div>
);
}
解釋:
-
isLoading用來判斷 API 是否正在執行 -
當使用者短時間連點,第二次點擊會直接被忽略
-
適合按鈕、表單送出、輸入框搜尋等操作
情境二:多個元件同時需要同一個 API
典型情境:多個元件都需要使用同一份資料,例如使用者資訊或設定
解決方法:共用 Promise 或全域快取,避免重複呼叫
範例:多元件共用同一個 API
import { useEffect, useState } from "react";
// 全域 Promise,共用 API 結果
let sharedApiPromise = null;
const fetchUserData = () => {
if (!sharedApiPromise) {
sharedApiPromise = fetch("https://jsonplaceholder.typicode.com/users/1")
.then((res) => res.json())
.finally(() => {
sharedApiPromise = null; // 下次可重新呼叫
});
}
return sharedApiPromise;
};
// 子元件
function UserProfile({ title }) {
const [user, setUser] = useState(null);
useEffect(() => {
fetchUserData().then((data) => setUser(data));
}, []);
if (!user) return <p>{title} 載入中...</p>;
return (
<div>
<h3>{title}</h3>
<p>姓名: {user.name}</p>
<p>Email: {user.email}</p>
</div>
);
}
export default function App() {
return (
<div>
<UserProfile title="元件 A" />
<UserProfile title="元件 B" />
</div>
);
}
解釋:
-
sharedApiPromise全域變數確保同一時間只有一個 API 請求 -
多個元件同時呼叫
fetchUserData(),會共用同一個 Promise -
適合初始化資料、共用設定、Profile API 等情境
方法總結
| 情境 | 適用方法 | 核心概念 |
|---|---|---|
| 同一個使用者動作短時間觸發多次 | flag / debounce / throttle | 防止重複呼叫,控制執行頻率 |
| 多個元件同時需要同一個 API | Promise 共用 / cache | 多元件共用資料,只呼叫一次 API |
透過以上方法,你可以在 React 專案中有效控制 API 呼叫次數:
-
使用旗標或防抖,避免同一個操作重複觸發
-
使用共用 Promise 或快取,讓多個元件共用資料,減少不必要的網路請求
這樣不僅能保護後端伺服器,也能讓前端效能更好、使用者體驗更順暢。