Создание пользовательского React‑хука для получения данных по указанному URL

Не запускайте fetch на каждом рендере: это создаст цикл запросов. Выполняйте его при изменении 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(...), второй отдаёт историю, третий — функцию повторного запроса. История общая только для этого экземпляра хука, не для всех компонентов приложения; порядок — от нового к старому.

ИИ-помощник для собеседований

Хочешь уверенно проходить собеседования?

Попробуй ИИ-помощник для собеседований: слышит вас и собеседника, анализирует экран, подсказывает ответы в реальном времени, работает без VPN и не попадает в захват экрана.

Подробнее