Reputation: 97
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
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
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