Striker
Striker

Reputation: 97

Infinite calls in axios.get

Following some tutorial, I made a todo app and is now working on connecting it to the database. But doing so, while making an axios.get request its been called indefinitely.

My code

import React from "react"
import Header from "./Header"   
import Footer from "./Footer"
import Note from "./Note"
import CreateArea from "./CreateArea"
import axios from "axios"

function App(){
    const [notes, setNotes] = React.useState([]);

    React.useEffect(()=>{
        axios.get('http://localhost:3001/user')
        .then(res=>{
            const entry = res.data;
            setNotes(()=>{
                return [...entry];
            })
        })
        .catch(err =>{
            console.log("Error: "+err);
        })
    })



    function addNote(newNote){
        axios.post('http://localhost:3001/user', newNote)
        .then(res=>{console.log(res.data)})
        .catch(err=>{console.log("Error: "+err)})
        setNotes((prevNotes)=>{
            return [...prevNotes, newNote];
        });
        console.log(newNote);
    }
    function deleteNote(id){
        setNotes(prevNotes =>{
            return prevNotes.filter((noteItem, index)=>{
                console.log(noteItem);
                return index !== id;
            });
        });
    }
    return (
        <div>
            <Header />
            <CreateArea onAdd={addNote} />

            {notes.map((noteItem, index)=>{
                return <Note key={index} id={index} title={noteItem.title} content={noteItem.content} onDelete={deleteNote} />
            })}

            <Footer />
        </div>
    )
}
export default App;

I looked around and landed on this thread Axios.get() ReactJS. Following this I added the useEffect but still infinite calls are being made.

Upvotes: 2

Views: 637

Answers (2)

Arun Kumar Mohan
Arun Kumar Mohan

Reputation: 11905

The effect is run infinitely since you're not passing an array of dependencies as the second argument to the useEffect call. Pass an empty array if you only want to run the effect when the component mounts.

From the docs:

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. This tells React that your effect doesn’t depend on any values from props or state, so it never needs to re-run. This isn’t handled as a special case — it follows directly from how the dependencies array always works.

React.useEffect(() => {
  axios
    .get('http://localhost:3001/user')
    .then((res) => {
      setNotes(res.data)
    })
    .catch((err) => {
      console.log('Error: ' + err)
    })
}, []) // an empty array of dependencies

If you set up eslint-plugin-react-hooks, it would display a warning to add setNotes to the dependency array since the effect depends on it. It's totally fine to add it since the function's reference won't change on re-renders.

React.useEffect(() => {
  axios
    .get('http://localhost:3001/user')
    .then((res) => {
      setNotes(res.data)
    })
    .catch((err) => {
      console.log('Error: ' + err)
    })
}, [setNotes])

This is unrelated to the question but you shouldn't hardcode the API URL. Use environment variables. If you're using Create React App, you can add environment variables prefixed with REACT_APP_ to .env or you can use dotenv-webpack if you have a custom Webpack setup.

Upvotes: 6

Mario Vernari
Mario Vernari

Reputation: 7304

Doing so, the useEffect is called on every function call. You should patch the code by adding something which never change overtime.

React.useEffect(()=>{
    //
    },
    []  //this makes the effect to be called the very first time only
)

Upvotes: 0

Related Questions