Why is the fetch statement in my react app resulting in two calls?

107 views Asked by At

Can anybody please explain to me why the fetch statement is resulting in 2 API calls? Both the chrome console and dev tools > network tab is showing two versions. The following is the code that I am using.

import React, { useState } from 'react';
import './contact.css';

const App = () => {

  const [contacts, setContacts] = useState([]);

  fetch("https://randomuser.me/api/?results=3")
  .then(response => response.json())
  .then(data => console.log(data));

  return (

    <>
      {
        contacts.map(contact => (
          <ContactCard
            avatar="https://via.placeholder.com/150"
            name={contact.name}
            email={contact.email}
            age={contact.age}
          />
        ))
      }
    </>
  )
};


const ContactCard = props => {

  const [showAge, setShowAge] = useState(false);

  return (
    <div className="contact-card">
      <img src="https://via.placeholder.com/150" alt="profile" />
      <div className="user-details">
        <p>Name: {props.name}</p>
        <p>Email: {props.email}</p>

        <button onClick={() => setShowAge(!showAge)}>{!showAge ? 'Show' : 'Hide'} Age</button>

        {
          showAge && <p>Age: {props.age}</p>
        }

      </div>
    </div>
  );
};

export default App;
1

There are 1 answers

5
ehab On BEST ANSWER
const App = () => {

  const [contacts, setContacts] = useState([]);
  // the issue is here, each time the component renders this statement will be exectuted
  fetch("https://randomuser.me/api/?results=3")
  .then(response => response.json())
  .then(data => console.log(data));

  // if you want to execute code after component is mounted into dom, use useEffect
  // like this

   useEffect(() => {
        fetch("https://randomuser.me/api/?results=3")
        .then(response => response.json())
        .then(data => console.log(data));
   }, []) // the second param for useEffect is dependencies array, pass an empty array if you want your effect to run only once (which is equivalent to componentDidMount in react class based components)
  return (

    <>
      {
        contacts.map(contact => (
          <ContactCard
            avatar="https://via.placeholder.com/150"
            name={contact.name}
            email={contact.email}
            age={contact.age}
          />
        ))
      }
    </>
  )
};