Reputation: 153
What I am trying to do?
I am trying to call an api that sends information and I want to render the information on to the react app. I have acheived what I wanted to however, there is a problem.
THE PROBLEM
React is firing unlimited request to the api as shown in the image below.
app.js
import React, { useState } from 'react';
import './css/main.css'
const App = () => {
const [data, setData] = useState([]);
fetch(`http://localhost/api/index.php`).then((res)=>{return res.json()}).then(
(data)=>{
setData(data)
}
)
return (
<div>
{data.length > 0 && (
<ul>
{data.map(ad => (
<li key={info.id}>
<h3>{info.name}</h3>
<p>{info.details}</p>
</li>
))}
</ul>
)}
</div>
);
}
export default App;
index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App';
ReactDOM.render(
<App />,
document.getElementById('root')
);
Upvotes: 3
Views: 130
Reputation: 636
The reason why this happens is that you are fetching data and update state on the fly that causing component to rerender, then to fetch data again, set state, rerender (getting stuck in a loop).
You should use useEffect
hook (read more here). Also, you can read more about data fetching on official documentation website here.
The whole fetch will be wrapped in a useEffect
hook.
useEffect(() => {
fetch(`http://localhost/api/index.php`).then((res)=>{return res.json()}).then(
(data)=>{
setData(data)
}
)
}, []);
Upvotes: 3
Reputation: 1
const renderData = () => {
fetch(`http://localhost/api/index.php`).then((res)=>{return res.json()}).then(
(data)=>{
setData(data)
}
}
useEffect(() => {
renderData();
},[]);
Upvotes: 0
Reputation: 4744
React calls the body of your component function on each render. In your case you:
So the solution is to use 'life cycles' by using something like useEffect, in which you can determine when to run your callback (the fetch()
in your case) - only on mounting the component, or when props change.
Upvotes: 0
Reputation: 2748
This is because you are setting the state in the API response itself and state change triggers re-render.
This happens as follows: fetch API call -> Data response -> set state -> trigger re-render -> fetch API call and the cycle continuous and result in infinite API call.
Solution: Call the API inside useEffect, useEffect is a hook that triggers once when the page renders or when its dependency changes.
Update your app.js as follows:
import React, { useState } from 'react';
import './css/main.css'
const App = () => {
const [data, setData] = useState([]);
useEffect(()=> {
fetch(`http://localhost/api/index.php`).then((res)=>{return res.json()}).then(
(data)=>{
setData(data)
}
),[]
}
return (
<div>
{data.length > 0 && (
<ul>
{data.map(ad => (
<li key={info.id}>
<h3>{info.name}</h3>
<p>{info.details}</p>
</li>
))}
</ul>
)}
</div>
);
}
export default App;
Upvotes: 1
Reputation: 673
you need to use useEffect(). The problem is when you set the data your component rendering from scratch and again fetching data and again setting and again again...
useEffect(() => {
fetch(`http://localhost/api/index.php`)
.then(res=>res.json())
.then(data=>setData(data))
}, []);
Upvotes: 1
Reputation:
Put fetch function inside useEffect and inside dependency array define when you want to run it. It will stop React from firing unlimited requests.
Upvotes: 0