'Fetch runs in a loop

I am fetching data in my react component

import React, { useState, useEffect } from 'react';
import { fetchBookData } from './bookData';
import "./App.css";

export default function Books ({ books }) {
  const [payload, setPayload] = useState(null)
    fetchBookData(books).then((payload) => setPayload(payload));
  return (
    <div className="App">
      <h1>Hello</h1>
    </div>
  );
}

Here is the fetch function itself

const dev = process.env.NODE_ENV !== 'production';
const server = dev ? 'http://localhost:3001' : 'https://your_deployment.server.com';
// later definable for developement, test, production

export const fetchBookData = (books) => {  
      const options = {
      method: `GET`,
      headers: {
        accept: 'application/json',
      },
    }; 
    return fetch(`${server}/books`, options)
    .then((response) => {
      if(response.ok){
        return response.json()
      }
        throw new Error('Api is not available') 
      })
    .catch(error => {
      console.error('Error fetching data in book data: ', error)
    })
}

But when I start the server fetch runs in a loop, component making endless get requests to the server. I tried to wrap it in a useEffect, but didn't work. Fetch should run once on load



Solution 1:[1]

If you want to run an effect and clean it up only once (on mount and unmount), you can pass an empty array ([]) as a second argument. More

example (codesandbox)

export default function App({books}) {
  const [payload, setPayload] = useState(null);

  useEffect(() => {
    fetchBookData(books).then((payload) => setPayload(payload));
  }, [books]);

  if (!payload) {
    return <h1>Loading...</h1>;
  }

  return (
    <div className="App">
      <h1>{payload.title}</h1>
    </div>
  );
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1