Пожалуйста, смотрите выше URL для очень упрощенной версии моего кода.

Я хочу иметь возможность повторно получать данные из API с помощью моего хука в течение некоторого интервала (в основном опрос конечной точки для данных).

Я хочу, чтобы у меня была возможность просто вызывать что-то вроде refetch (как я показал в коде в качестве комментария), что по сути просто снова вызывает fetchData и обновляет состояние с ответом соответственно.

Какой лучший способ пойти по этому поводу? Единственный способ, о котором я могу подумать, - это добавить в ловушку переменную checker , которая была бы своего рода uuid (возможно, Math.random () ), вернуть Задайте для параметра refetch значение и просто добавьте checker в массив в качестве второго аргумента useEffect для управления повторной визуализацией. Поэтому, когда вы вызываете refetch , он вызывает setChecker , который обновляет случайное число ( checker ), а затем функция запускается снова.

Очевидно, это звучит «хакерски», должен быть более хороший способ сделать это - есть идеи?

0
Apswak

2 ответа

import React, { useEffect, useState, useCallback } from "react";
import ReactDOM from "react-dom";

const url = "https://api.etilbudsavis.dk/v2/dealerfront?country_id=DK";

function useFetch() {
  const [data, setDataState] = useState(null);
  const [loading, setLoadingState] = useState(true);
  const refetch = useCallback(() => {
    function fetchData() {
      console.log("fetch");
      setLoadingState(true);
      fetch(url)
        .then(j => j.json())
        .then(data => {
          setDataState(data);
          setLoadingState(false);
        });
    }
    fetchData();
  }, []);

  return [
    {
      data,
      loading
    },
    refetch
    // fetchData <- somehow return ability to call fetchData function...
  ];
}

function App() {
  const [
    { data, loading },
    refetch
    // refetch
  ] = useFetch();

  useEffect(() => {
    const id = setInterval(() => {
      // Use the refetch here...
      refetch();
    }, 5000);
    return () => {
      clearInterval(id);
    };
  }, [refetch]);

  if (loading) return <h1>Loading</h1>;
  return (
    <>
      <button onClick={refetch}>Refetch</button>
      <code style={{ display: "block" }}>
        <pre>{JSON.stringify(data[0], null, 2)}</pre>
      </code>
    </>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

Если вы хотите, чтобы проводился постоянный опрос, я думаю, вы можете переместить setInterval () в ловушку следующим образом:

function useFetch() {
  const [data, setDataState] = useState(null);
  const [loading, setLoadingState] = useState(true);
  useEffect(() => {
    function fetchData() {
      setLoadingState(true);
      fetch(url)
        .then(j => j.json())
        .then(data => {
          setDataState(data);
          setLoadingState(false);
        });
    }

    const interval = setInterval(() => {
      fetchData();
    }, 5000);

    fetchData();

    return () => clearInterval(interval);
  }, []);

  return [
    {
      data,
      loading
    }
  ];
}

Не забудьте включить return () => clearInterval(interval);, чтобы хук правильно очищался.

58584289