Не запускайте fetch на каждом рендере: это создаст цикл запросов. Выполняйте его при изменении URL или явной перезагрузке, накапливая успешно полученные ответы в состоянии хука.
Создание пользовательского React‑хука для получения данных по указанному URL
Не запускайте fetch на каждом рендере: это создаст цикл запросов. Выполняйте его при изменении URL или явной перезагрузке, накапливая успешно полученные ответы в состоянии хука.
Короткий ответ
Что ответить на собеседовании
Подробный разбор
Ответ с пояснениями
Условие
Необходимо написать собственный хук useFetch, который принимает строку‑URL, инициирует HTTP‑запрос к этому адресу, сохраняет полученный ответ и возвращает его. При каждом вызове хук должен добавлять полученные результаты в общий массив и отдавать его вызывающему компоненту.
import { useEffect, useState } from "react";
export default function App() {
const counter = 0;
const [data, setData] = useState("");
const [joke] = useFetch("https://api.chucknorris.io/jokes/random");
useEffect(() => {
console.log("was", joke);
setData(joke?.value);
}, [joke]);
return (
<div className="App">
<h1>Открой консоль {data}</h1>
</div>
);
}
Ответ
Не запускайте fetch на каждом рендере: это создаст цикл запросов. Выполняйте его при изменении URL или явной перезагрузке, накапливая успешно полученные ответы в состоянии хука.
function useFetch(url) {
const [history, setHistory] = useState([]);
const [version, setVersion] = useState(0);
const [error, setError] = useState(null);
useEffect(() => {
const controller = new AbortController();
let active = true;
setError(null);
(async () => {
try {
const response = await fetch(url, { signal: controller.signal });
if (!response.ok) throw new Error('Ошибка HTTP');
const data = await response.json();
if (active) setHistory(previous => [data, ...previous]);
} catch (failure) { if (active) setError(failure); }
})();
return () => { active = false; controller.abort(); };
}, [url, version]);
return [history[0], history, () => setVersion(value => value + 1), error];
}
useEffect/useState импортируются как в условии. Первый элемент сохраняет совместимость с const [joke] = useFetch(...), второй отдаёт историю, третий — функцию повторного запроса. История общая только для этого экземпляра хука, не для всех компонентов приложения; порядок — от нового к старому.