简体   繁体   中英

Why is my custom useFetch hook causing an infinite loop?

This is the react custom hook that I use to fetch data throughout my App. I did not encounter problems when I used this hook to fetch data based on user's input query.

useFetch.jsx

import React, { useState, useEffect } from "react";
import apiKey from "../apiKey";

function useFetch() {
  const [data, setData] = useState(null);
  const [error, setError] = useState(null);
  const [loading, setLoading] = useState(false);

  async function fetchData(
    url,
    options = {
      method: "GET",
      headers: {
        "X-RapidAPI-Key": apiKey,
        "X-RapidAPI-Host": "unogsng.p.rapidapi.com",
      },
    }
  ) {
    setLoading(true);
    try {
      const response = await fetch(url, options);
      const jsonData = await response.json();
      setData(jsonData);
    } catch (err) {
      setError(err);
    }
    setLoading(false);
  }

  return [data, error, loading, fetchData];
}

export default useFetch;

This is the homepage of my App. I want the homepage to display the newest shows that are released today. I encountered an infinite loop when I tried to use useEffect to fetch the API.

Home.jsx

import React, { useState, useEffect } from "react";
import useFetch from "../hooks/useFetch";

const Home = () => {
  const [newShows, setNewShows] = useState([]);
  const [data, error, loading, fetchData] = useFetch();
  const today = new Date();
  const date = today.toISOString().substring(0, 10);
  const url = `https://unogsng.p.rapidapi.com/search?newdate=${date}&limit=10`;
  console.log(date);

  useEffect(() => {
    fetchData(url);
    console.log(data);
  }, [data]);

  return <h1>Home</h1>;
};

export default Home;

I tried using url as dependency but it did not fetch the API on mount.

  useEffect(() => {
    fetchData(url);
    console.log(data);
  }, [url]);

It does't work with no dependency either.

  useEffect(() => {
    fetchData(url);
    console.log(data);
  }, []);

Fetch the data only when the component mounts; so use an empty dependency array for useEffect . (You might want to put url in the dependency array if it may change.)

useEffect(() => {
  fetchData(url);
}, []);

Then, display the data conditionally in the JSX:

return <>
  <h1>Home</h1>
  {data ? <pre>{JSON.stringify(data, null, 4)}</pre> : <p>Loading</p>}
</>;

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM