我可以这样做吗:
const [borderCountries, setBorderCountries] = useState([])
useEffect(() => {
country.borders.forEach(c => {
fetch(`https://restcountries.eu/rest/v2/alpha/${c}`)
.then(res => res.json())
.then(data => setBorderCountries([...borderCountries,data.name]))
})
}, [])
国家边界是传递给组件的道具。如果没有,我该怎么办?
答案 0 :(得分:5)
您可以,但不完全是这样,原因如下:
borderCountries
而不是使用 setBorderCountries
的回调版本。useEffect
依赖项数组中列出该道具。最小的变化是使用回调版本:
.then(data => setBorderCountries(borderCountries => [...borderCountries,data.name]))
// ^^^^^^^^^^^^^^^^^^^
...并将 country.borders
添加到 useEffect
依赖项数组。
这将更新您组件的状态每次 fetch
完成。
或者,收集所有更改并立即应用它们:
Promise.all(
country.borders.map(c =>
fetch(`https://restcountries.eu/rest/v2/alpha/${c}`)
.then(res => res.json())
.then(data => data.name)
})
).then(names => {
setBorderCountries(borderCountries => [...borderCountries, ...names]);
});
无论如何,请注意以下几点:
您的代码正在成为 fetch
API 中的猎物的牺牲品:它只拒绝对 网络 故障的承诺,而不是 HTTP 错误。在调用 ok
之前检查 response
对象上的 .json()
标志以查看是否存在 HTTP 错误。关于in my blog post here的更多信息。
您应该处理 fetch
失败的可能性(无论是网络错误还是 HTTP 错误)。您的代码中目前没有任何内容处理承诺拒绝。至少添加一个报告错误的 .catch
。
由于 country.borders
是一个属性,您可能希望取消任何先前仍在进行的 fetch
操作,至少如果它正在获取的边框不在列表中。
将 #1 和 #2 放在一起,但将 #3 作为练习留给读者(尤其是因为您如何/是否处理这取决于您的用例,尽管对于取消部分,您会使用 {{3 }}),如果每次有结果都想更新
const [borderCountries, setBorderCountries] = useState([]);
useEffect(() => {
country.borders.forEach(c => {
fetch(`https://restcountries.eu/rest/v2/alpha/${c}`)
.then(res => {
if (!res.ok) {
throw new Error(`HTTP error ${res.status}`);
}
return res.json();
})
.then(data => setBorderCountries(borderCountries => [...borderCountries, data.name]))
// ^^^^^^^^^^^^^^^^^^^
.catch(error => {
// ...handle and/or report the error...
});
});
}, [country.borders]);
// ^^^^^^^^^^^^^^^
或进行一次更新:
const [borderCountries, setBorderCountries] = useState([]);
useEffect(() => {
Promise.all(
country.borders.map(c =>
fetch(`https://restcountries.eu/rest/v2/alpha/${c}`)
.then(res => res.json())
.then(data => data.name)
})
)
.then(names => {
setBorderCountries(borderCountries => [...borderCountries, ...names]);
})
.catch(error => {
// ...handle and/or report the error...
});
}, [country.borders]);
// ^^^^^^^^^^^^^^^
答案 1 :(得分:-1)
你可以,但这不是一个好习惯。