Запит при першому рендері
Коротко: роби запит у useEffect з порожнім масивом залежностей [] (тільки при першому монтуванні), не забувай про скасування і обробку помилок. Нижче - надійний шаблон.
javascript
import { useEffect, useState, useRef } from "react";
export function UserOnce() {
const [data, setData] = useState(null);
const [error, setError] = useState(null);
const [loading, setLoading] = useState(true);
// Страховка від подвійного виклику ефекту в Dev-режимі (StrictMode) у React 18
const didRunRef = useRef(false);
useEffect(() => {
if (didRunRef.current) return; // не даємо запуститися вдруге в Dev
didRunRef.current = true;
const controller = new AbortController();
(async () => {
try {
setLoading(true);
const res = await fetch("/api/user", { signal: controller.signal });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const json = await res.json();
setData(json); // оновлюємо стан тільки якщо не скасували
} catch (e) {
if (e.name !== "AbortError") setError(e);
} finally {
setLoading(false);
}
})();
// cleanup: скасовуємо запит при демонтуванні
return () => controller.abort();
}, []); // ← тільки перший рендер (монтування)
if (loading) return <p>Loading...</p>;
if (error) return <p>Error: {String(error.message || error)}</p>;
return <pre>{JSON.stringify(data, null, 2)}</pre>;
}Важливі моменти
-
Чому
[]: ефект виконається один раз - при монтуванні компонента. -
StrictMode в Dev (React 18): ефекти можуть викликатися двічі. Прапорець
useRefвище запобігає повторному запиту при розробці. У проді ефект виконається один раз. -
Скасування запиту:
AbortController- must-have, щоб не ловитиsetStateна демонтованому компоненті і не витрачати мережу. -
Звідки брати параметри: якщо запит залежить від
props/state(наприклад,userId), включай їх у залежності:javascriptuseEffect(() => { // ...запит з userId... }, [userId]);
і показуй loading при зміні userId.
- Альтернатива: бібліотеки на кшталт TanStack Query (React Query) і SWR беруть на себе кеш, скасування, повтор, stale-while-revalidate тощо, спрощуючи код.
Коротка відповідь
Для співбесідиPremium
Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.