|
- ---
- description: Prevent double-click / duplicate API calls from frontend UI
- alwaysApply: true
- ---
-
- # Prevent duplicated API calls (frontend)
-
- When wiring UI actions (buttons, row actions, dialogs) to backend APIs, **always prevent double submission**. Relying on `setState` + `disabled` alone is not sufficient because rapid double-click can fire twice before React re-renders.
-
- - **Must**: add an **in-flight lock** (e.g. `useRef(false)`) and early-return if already running.
- - **Must**: keep the UI disabled/loading (`disabled={isLoading}`) for user feedback.
- - **Must**: clear the lock in `finally` so it always releases.
- - **Should**: if the same endpoint can be triggered from multiple places, consider a shared “single-flight” helper (dedupe by `method+url+body` key).
-
- Example pattern:
-
- ```tsx
- const inFlightRef = useRef(false);
- const [isSaving, setIsSaving] = useState(false);
-
- const onSave = async () => {
- if (inFlightRef.current) return;
- inFlightRef.current = true;
- setIsSaving(true);
- try {
- await doRequest();
- } finally {
- setIsSaving(false);
- inFlightRef.current = false;
- }
- };
- ```
|