Search code examples
javascriptreactjsfetch

React fetch data fires over and over again


Does anyone know why this fetch continues to fire. I have also tried putting it inside a useEffect with no luck. It should only fire once to return once imdbID has loaded.

const WatchOnList = ({ imdbId }) => {
  const [locations, setLocations] = useState([])
  var headers = new Headers();
  headers.append("x-api-key", "API_KEY")

  var requestOptions = {
    method: 'GET',
    headers: headers,
    crossDomain: true,
    redirect: 'follow'
  };

  async function fetchData() {
    const res = await fetch(`${awsApiUrl}?imdb_id=${imdbId}`, requestOptions);
    res
      .json()
      .then((res) => {
        setLocations(res)
        console.log(locations)
      })
      .catch(error => console.log('error', error));
  }
  fetchData();

Solution

  • With the current structure, the request will fire on every re-render. Which will be quite often in a React app. useEffect is the right place for such a function. But there are some caveats:

    1. You can't make useEffect async, you have to create an async function inside the hook instead and call it afterward.
    2. useEffect will per default run on every update, so you have to tell it explicitly to only run once (like componentDidMount for class components). This can be done by passing an empty array as the second parameter. The hook watches parameters specified in this array and only updates when one of them changes. As it is empty, it only fires once on initialization.

    This should work:

     useEffect(() => {
        async function fetchData() {
          const res = await fetch(`${awsApiUrl}?imdb_id=${imdbId}`, requestOptions);
          res
            .json()
            .then(res => {
              setLocations(res);
              console.log(locations);
            })
            .catch(error => console.log("error", error));
        }
        fetchData();
      }, []);
    

    Read more about the behavior of hooks here and here.