0

Pardon me if this is a silly question. Im a new react learner. Im trying using a create react app. I am using a custom hook for API handling only. Now I want the useEffect to run only when the data changes. Thats why I put it in dependency. But yet it keeps rendering for infinity. What is the problem? Or how should I handle this? Thank you.

import { useCallback, useEffect, useState } from "react";

export const useAPI = (url, options) => {
    const [data, setData] = useState([]);

    const getDogCollection = useCallback(() => {
        fetch(url, options)
            .then((res) => res.json())
            .then((result) => {
                console.log(data, "----DI---", result);
                setData(result);
            });
    }, []);

    useEffect(() => {
        getDogCollection();
    }, [data]);

    return data;
};

2 Answers2

1

You'll just want url and options to be the dependencies, not data (because you set it in the effect!).

import { useEffect, useState } from "react";

export const useAPI = (url, options) => {
  const [data, setData] = useState([]);
  useEffect(() => {
    fetch(url, options)
      .then((res) => res.json())
      .then(setData);
    // TODO: add error handling...
  }, [url, options]);
  return data;
};

However, you'll probably just want to look at swr instead of writing this hook yourself.

AKX
  • 152,115
  • 15
  • 115
  • 172
  • I actually already did that. And I know it could solve the issue. I was more of looking for the answer of why the data being the same yet keeps looping. I have the answer now. Thanks a lot for the help man <3 – Cnerd Mahadi Feb 07 '23 at 17:29
0

It's because you've given data as one of the dependencies, but the function called in your useEffect updates data, so it then runs again.

You can change it to the length, like this, and it should work:

useEffect(() => {
    getDogCollection();
}, [data.length]);
Gordon Maloney
  • 262
  • 1
  • 11
  • 1
    This will cause at least one extra fetch of dogs. I don't think that's what OP wants. – AKX Feb 07 '23 at 13:37
  • Thanks a ton. So far this seems like the solution I was looking for. I know I could just add an empty dependency array to avoid the issue. But I was looking for the answer that why even if it is the same data yet keeps looking. I have my answer now. Its because the data as object although the value is same yet every time returns a new object. and length or any primitive data type can solve the issue. – Cnerd Mahadi Feb 07 '23 at 17:27
  • @CnerdMahadi Just so you know, this will _not_ do the right thing if the dogs change but there's the same amount of them... – AKX Feb 07 '23 at 18:21
  • @AKX, Could you explain brother? I quite didnt get what you said. – Cnerd Mahadi Feb 08 '23 at 10:58