英文:
Facing problem when fetching data using a fake API using 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}>获取数据</button>
{loading ? <h1>加载中...</h1> : <h1>{data.title}</h1>}
</div>
)
}
export default FetchData
请注意,代码部分已经翻译成中文。
英文:
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
答案1
得分: 0
根据您提供的条件,useEffect
中的代码仅在 id 不同的情况下才会被执行。当您再次按下按钮时,id 保持不变,因此useEffect
中的代码不会运行,并且在 idUpdater
中设置的 loading 状态将保持为 true。
更好的方法是在初始挂载时调用 fetch,并在按钮按下时重用该函数,如下所示:
import React, { useState, useEffect } from "react";
const FetchData = () => {
const [data, setData] = useState({});
const [value, setValue] = useState(1);
const [loading, setLoading] = useState(true);
const idUpdater = () => {
setLoading(true);
fetchData(value);
};
const fetchData = async (pageNo) => {
const data = await fetch(
`https://jsonplaceholder.typicode.com/posts/${pageNo}`
);
const response = await data.json();
setData(response);
setLoading(false);
};
useEffect(() => {
fetchData(1);
}, []);
return (
<div>
<input
type="text"
value={value}
onChange={(e) => setValue(e.target.value)}
/>
<button onClick={idUpdater}>获取数据</button>
{loading ? <h1>加载中...</h1> : <h1>{data.title}</h1>}
</div>
);
};
export default FetchData;
英文:
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:
import React, { useState, useEffect } from "react";
const FetchData = () => {
const [data, setData] = useState({});
const [value, setValue] = useState(1);
const [loading, setLoading] = useState(true);
const idUpdater = () => {
setLoading(true);
fetchData(value);
};
const fetchData = async (pageNo) => {
const data = await fetch(
`https://jsonplaceholder.typicode.com/posts/${pageNo}`
);
const response = await data.json();
setData(response);
setLoading(false);
};
useEffect(() => {
fetchData(1);
}, []);
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;
答案2
得分: 0
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])
在方括号内的依赖项表示,每当 id
发生变化时,这个 useEffect
将被触发。
在你的情况下,当重新点击 "Get data" 按钮时,setLoading(true)
被调用,将你的界面置于 "Loading..." 状态,setId(value)
也被调用,但值没有改变(仍然是3),因此 useEffect
不会被触发。
英文:
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])
The dependencies inside the square brackets means, this useEffect
will be triggered everytime the id
changes.
In your case, when re-clicking the Get data
button, setLoading(true)
runs make your ui runs into Loading... state, the setId(value)
also runs but the value does not change (still 3) therefore the useEffect
is not triggered
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论