kalpeshshende
kalpeshshende

Reputation: 153

React firing unlimited requests

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')
);

React firing unlimited api requests

Upvotes: 3

Views: 130

Answers (6)

Victor
Victor

Reputation: 636

Why is it not working?

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).

How to solve?

You should use useEffect hook (read more here). Also, you can read more about data fetching on official documentation website here.

What will change in your code?

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

Vatsal
Vatsal

Reputation: 1

const renderData = () => {
  fetch(`http://localhost/api/index.php`).then((res)=>{return res.json()}).then(
      (data)=>{
        setData(data)
      }
}
useEffect(() => {
renderData();
},[]);

Upvotes: 0

Alserda
Alserda

Reputation: 4744

React calls the body of your component function on each render. In your case you:

  • Perform a request,
  • Upon completing the request, you set the state of your useState hook,
  • The state triggers a re-render,
  • The cycle repeats.

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

Ritik Banger
Ritik Banger

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

Garo Gabrielyan
Garo Gabrielyan

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

user19786344
user19786344

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

Related Questions