cki*_*ris 0 javascript reactjs fetch-api use-effect use-state
为什么会fetchData多次触发?在console.log似乎环几乎是无限?如何让它在加载时仅运行一次并在fetchData()稍后调用时仅触发一次?我在这里做错了什么或错过了什么?
const [data, setData] = useState(null);
let fetchData = React.useCallback(async () => {
const result = await fetch(`api/data/get`);
const body = await result.json();
setData(body);
console.log(data)
},[data])
useEffect(() => {
fetchData();
},[fetchData]);
Run Code Online (Sandbox Code Playgroud)
更新(附加问题):如何在下面data的之前等待填充return()现在给出错误,因为它最初为空?:data.map is not a function
return (
<select>
{data.map((value, index) => {
return <option key={index}>{value}</option>
})}
</select>
)
Run Code Online (Sandbox Code Playgroud)
在useCallback钩子中,您data作为依赖项传递,同时通过调用在回调中更改数据的值setData,这意味着每次更改的数据值fetchData都将重新初始化。
在useEffect挂钩fetchData是一个依赖,这意味着每一次fetchData变化useEffect都会被触发。这就是为什么你会得到一个无限循环。
因为要在组件挂载时取一次数据,所以我觉得useCallback这里没必要。没有必要fetchData不必要地记住函数。
解决方案
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const result = await fetch(`api/data/get`);
const body = await result.json();
setData(body);
} catch(err) {
// error handling code
}
}
// call the async fetchData function
fetchData()
}, [])
Run Code Online (Sandbox Code Playgroud)
如果你想记录data它改变时的值,你可以使用另一个useEffect来代替。例如,
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
try {
const result = await fetch(`api/data/get`);
const body = await result.json();
setData(body);
} catch(err) {
// error handling code
}
}
// call the async fetchData function
fetchData()
}, [])
Run Code Online (Sandbox Code Playgroud)
PS - 也不要让承诺未得到处理,请使用try...catch块来处理错误。我已更新解决方案以包含 try..catch 块。
编辑-附加问题的 解决方案有两种可能的解决方案,
因为您希望dataAPI 调用后的值是一个数组,所以您可以将 data 的值初始化为一个空数组,例如,
useEffect(() => {
console.log(data)
}, [data])
Run Code Online (Sandbox Code Playgroud)
但是如果由于某种原因你必须初始化dataas的值null。以下是呈现从 API 调用返回的信息的方法。
const [data, setData] = useState([]);
Run Code Online (Sandbox Code Playgroud)
不要使用indexesas key,为密钥使用唯一的东西。
| 归档时间: |
|
| 查看次数: |
2345 次 |
| 最近记录: |