I am trying to fetch data from the server using react fetch function, but it's making endless calls to the API
I am returning an array from the API, which only needs a single API call but fetch() makes infinite calls regardless of the endpoint.
function Posts(){
const classes = useStyles();
const [data, setData] = useState({posts : [{
title : ''
}]});
fetch('')
.then( res => res.json())
.then( data => {
setData({posts: data})
})
return(
<Container className={classes.container}>
</Container>
)
}
I expect it to make only single or two calls so that it doesn't spam the server.
I am trying to fetch data from the server using react fetch function, but it's making endless calls to the API
I am returning an array from the API, which only needs a single API call but fetch() makes infinite calls regardless of the endpoint.
function Posts(){
const classes = useStyles();
const [data, setData] = useState({posts : [{
title : ''
}]});
fetch('https://jsonplaceholder.typicode./posts')
.then( res => res.json())
.then( data => {
setData({posts: data})
})
return(
<Container className={classes.container}>
</Container>
)
}
I expect it to make only single or two calls so that it doesn't spam the server.
Share Improve this question edited Jul 19, 2019 at 12:45 Udit asked Jul 19, 2019 at 11:17 UditUdit 3935 silver badges15 bronze badges 11-
2
Where exactly did you put that call? In
ponentDidMount()
like you're supposed to? Because if you put that inrender()
you'll get an infinite loop.setState
causes a re-render, and thus cannot be insiderender()
. You should have a warning alluding to this in your browser console. – user5734311 Commented Jul 19, 2019 at 11:20 - 1 Exactly as suggested by @ChrisG. Post the full code. You must have a maximum update depth exceeded error in your console. – Rohit Kashyap Commented Jul 19, 2019 at 11:25
-
1
In the OP case I guess?
setData
is not an official React function. – user5734311 Commented Jul 19, 2019 at 11:31 -
2
Nobody can guess why until you provide a minimal reproducible example. Showing us only a simple
fetch()
will not create the symptoms described on it's own – charlietfl Commented Jul 19, 2019 at 11:31 -
1
You're doing
fetch()
again every time the function is called, and the function is called when you dosetData()
which leads to the infinite loop. You have to use effects for anything that changes the state like Ajax calls. – JJJ Commented Jul 19, 2019 at 13:06
2 Answers
Reset to default 3To ensure that only a single API call is made, call the fetch function inside ponentDidMount()
lifecycle method of your ponent.
ponentDidMount()
method is called after the ponent is mounted into the DOM and it is called only once in a ponent's lifecycle.
You can also then use setState()
method to set the received data into your state.
Check below code,
class A extends Component{
ponentDidMount() {
fetch('https://jsonplaceholder.typicode./posts')
.then( res => res.json())
.then( data => {
this.setState({posts: data})
})
}
render() {
// your code
}
}
Note: Calling setState()
inside render()
method can cause the ponent to re-render and hence executing in infinite loop.
If you are using functional ponent then useEffect()
can be used to fetch the data only once when the ponent is mounted. Check ReactJS: how to call useEffect hook only once to fetch API data
import React, {useState, useEffect} from 'react';
wrapping fetch inside useEffect()
solved the issue,
function Posts(){
const classes = useStyles();
const [data, setData] = useState({posts : [{
title : ''
}]});
useEffect(() => {
fetch('https://jsonplaceholder.typicode./posts')
.then( res => res.json())
.then( data => {
setData({posts: data})
})
}, []);
useEffect()
only after the render, we can also choose to run it if any value changes.