JCe*_*Rdz 2 javascript reactjs react-hooks
我可以这样做吗:
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]))
})
}, [])
Run Code Online (Sandbox Code Playgroud)
国家边界是传递给组件的道具。如果不是,我能做什么?
您可以,但不完全是这样,原因如下:
borderCountries直接使用setBorderCountries.useEffect依赖项数组中列出该道具。最小的变化是使用回调版本:
.then(data => setBorderCountries(borderCountries => [...borderCountries,data.name]))
// ^^^^^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
...并添加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]);
});
Run Code Online (Sandbox Code Playgroud)
无论哪种方式,有几个注意事项:
您的代码正在成为fetchAPI中的猎物:它只拒绝网络故障的承诺,而不是 HTTP 错误。在调用对象之前检查对象ok上的标志以查看是否存在 HTTP 错误。有关更多信息,请参阅我的博客文章。response.json()
您应该处理fetch失败的可能性(无论是网络错误还是 HTTP 错误)。您的代码中目前没有任何内容处理承诺拒绝。至少,添加一个.catch报告错误。
由于country.borders是一个属性,您可能希望取消任何先前fetch仍在进行的操作,至少如果它正在获取的边框不在列表中。
将 #1 和 #2 放在一起,但将 #3 作为练习留给读者(尤其是因为您如何/是否处理这取决于您的用例,但对于您将使用的取消部分AbortController),如果您想每次得到结果时更新
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]);
// ^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
或者对于一个更新:
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]);
// ^^^^^^^^^^^^^^^
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
64 次 |
| 最近记录: |