I am a beginner in react and trying a basic example where I am fetching data based on what I am passing in input field , the value in input field goes as id to the API URL , Everything is working fine but
this fails for a particular case . Suppose I entered 3 in input field and then click the button , First time the data shows as expected , but if I again press the get data button the UI just stuck showing Loading…
I think it is related to dependency array in useEffect.
import React,{useState,useEffect} from 'react'
const FetchData = () => {
const [data,setData]=useState({})
const [value,setValue]=useState(1)
const [id,setId]=useState(1)
const [loading,setLoading]=useState(true)
const idUpdater=()=>{
setLoading(true)
setId(value)
}
useEffect(()=>{
const fetchData= async()=>{
const data=await fetch(`https://jsonplaceholder.typicode.com/posts/${id}`)
const response=await data.json()
setData(response)
setLoading(false)
}
setTimeout(fetchData,2000)
},[id])
return (
<div>
<input type="text" value={value} onChange={(e)=>setValue(e.target.value)} />
<button onClick={idUpdater}>Get Data</button>
{loading?<h1>Loading...</h1>:<h1>{data.title}</h1>}
</div>
)
}
export default FetchData
I tried removing the dependency array , but it didn’t work
2
Answers
Based on the condition you have given the code in useEffect gets only rendered when the id is different. When you press the button again the id remains same thus the code inside useEffect won’t run and the loading state set in idUpdater will remain true.
A better approach to this would be calling fetch on initial mount and reusing that function on button press, as:
Check demo
The dependencies inside the square brackets means, this
useEffect
will be triggered everytime theid
changes.In your case, when re-clicking the
Get data
button,setLoading(true)
runs make your ui runs into Loading… state, thesetId(value)
also runs but the value does not change (still 3) therefore theuseEffect
is not triggered