6

React Fetch API Being Called 2 Times on page load, I don't know what is missing in this code or what I am doing wrong. I have faced this problem from the morning, I really appreciate any help you can provide.

import React, { useState, useEffect } from 'react' import axios from 'axios'; import { Grid, Paper, TextField } from '@mui/material' import PersonOutlineIcon from '@mui/icons-material/PersonOutline'; function FormApi() { //Mui fileds and paper style const paperStyle = { padding: '50px ', width: 550, margin: '50px auto' } //Fetch data from api const [userx, setUserx] = useState([{data:null,support:null}]); const url = 'https://reqres.in/api/users/2'; useEffect(()=>{ //debugger const fetchData = async () =>{ await axios.get(`${url}`) .then((response) =>{ setUserx(response.data) }).catch((error)=>{ console.log(error) }) } fetchData(); } ,[]); return ( <Grid container spacing={2} style={paperStyle}> <Grid align='center' > <Paper elevation={20} > <Grid align='center'> <h2 style={{padding:'10px' ,background: "#000080", color: 'white' }}> <PersonOutlineIcon large style={{fontSize:'80%'}} />User Details</h2> </Grid> <form> <img style={{width:"20%"}} src={userx.data ? userx.data.avatar : ''}/> <h1 style={{color:'#000080'}}>{userx.data ? userx.data.first_name : ''} {userx.data ? userx.data.last_name : ''}</h1> <Grid container > <Grid item xs={6} > <h2 style={{color:'white', background: "purple"}}>Contact Info</h2> <TextField value={userx.data ? userx.data.id : ''} variant="standard" /> <TextField value={userx.data ? userx.data.email : ''} variant="standard" /> </Grid> <Grid item align='left' xs={6} style={{marginBottom:'40px'}}> <h2 style={{color:'white', background: "purple"}}>Social Link</h2> <TextField value={userx.support ? userx.support.url : ''} variant="standard" /> <TextField value={userx.support ? userx.support.text : ''} variant="standard" /> </Grid> </Grid> </form> </Paper> </Grid> </Grid> ) }enter code here export default FormApi 
2
  • 3
    Do you have StrictMode enabled? Commented May 27, 2022 at 13:55
  • This is normal behaviour in React 18 reactjs.org/docs/strict-mode.html#ensuring-reusable-state. It will only be done on development environments and when StrictMode is enabled. Commented May 27, 2022 at 13:58

5 Answers 5

23

It's because React renders components 2 times in the development environment. To avoid this, you can comment out the <React.StrictMode> tag in index.js file.

Rendering twice will only appear in the development environment and StrictMode has many benefits for development:

  • Identifying components with unsafe lifecycles
  • Warning about legacy string ref API usage
  • Warning about deprecated findDOMNode usage
  • Detecting unexpected side effects
  • Detecting legacy context API
  • Ensuring reusable state

So it's better to keep the <React.StrictMode> tag if it doesn't affect your normal development work.

See also: React StrictMode

Sign up to request clarification or add additional context in comments.

Comments

10

You can handle it with useRef hook, but it's totally fine. it happens only in dev mode.

const renderAfterCalled = useRef(false); useEffect(() => { if (!renderAfterCalled.current) { // your API call func } renderAfterCalled.current = true; }, []); 

removing <React.StrictMode> can also solve the issue but avoid removing <React.StrictMode>. it's a helpful tool during development that checks for potential issues and warns about unsafe practices.

1 Comment

It's not really fine if the call is computationally intensive, though, is it?
8

This is normal behaviour in React 18. It will only be done on development environments and when StrictMode is enabled and will not be a problem in your production Build.

A bit annoying, but nothing really to worry about. There is a workaround which you can learn more about in a in-depth answer here: React 18, useEffect is getting called two times on mount

Comments

0

as much as I know, this issue is caused by the HTTTP client sending 2 request, one to the route path "/" and the other to "/favicon.ico"

make this change :

useEffect(()=>{ checkLocation(); //your code ,[]); 

2 Comments

What? fetch doesn't ask for a favicon unless you specifically make that request.
Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
-1

after some revision try this

function FormApi() {

 //Mui fileds and paper style const paperStyle = { padding: '50px ', width: 550, margin: '50px auto' } //Fetch data from api const [userx, setUserx] = useState([{data:null,support:null}]); const url = 'https://reqres.in/api/users/2'; //debugger const fetchData = async () =>{ await axios.get(`${url}`) .then((response) =>{ setUserx(response.data) }).catch((error)=>{ console.log(error) }) } useEffect(()=>{ fetchData(); } ,[]); 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.