如何解决React 无法更新状态
我不知道为什么我不能更新我的状态(请参阅 setCoords)。请求返回 200 代码并且我尝试检索的元素存在:
这是我的代码:
let values = Array(24).fill(0);
感谢您的帮助!
解决方法
试试 useCallback
...
const onSearch = useCallback(async () {
if (city) {
await apiGet(`/geo/1.0/direct?q=${city}`)
.then(r => r.json())
.then(r => setCoords({lat: r[0].lat,lon:r[0].lon})); // doesn't't set anything
await console.log(coords) // console logs {}
await apiGet(
`/data/2.5/onecall?lat=${coords.lat}&lon=${coords.lon}&exclude=current,minutely,hourly,alerts`
)
.then(r => r.json())
.then(r => setForecast(r));
}
},[coords]);
...
参考:https://reactjs.org/docs/hooks-reference.html#usecallback
,需要注意的一点是,不要将 await
与 then
混合使用(更多信息:Can await and then be mixed in one implementation?)。由于您使用的是 async
,我建议您将所有更改为 await
,如下所示
另一件需要注意的事情是 setStates
调用(即 setCoords
和 setForecast
和 setCity
)本质上是异步,这意味着立即console.log
设置状态后将不记录刚刚更新的值。相反,React 会将这些 setState 安排到下一次渲染 - 因此,您只能在下一个渲染周期中查看/访问最新更新的值。如果您想记录值,您可以将它们放在 HTML 中的 <pre>
标记中,或者在开头执行 console.log
,如下所示:
const App = () => {
const [city,setCity] = useState("");
const [forecast,setForecast] = useState(null);
const [coords,setCoords] = useState({});
console.log("City",city,"Forecast",forecast,"Coords",coords);
const handleSearchChange = ev => {
setCity(ev.target.value);
};
async function onSearch() {
if (city) {
const resNonJson = await apiGet(`/geo/1.0/direct?q=${city}`)
const resJson = await resNonJson.json())
const item = resJson[0];
setCoords({lat: item.lat,lon: item.lon}));
// Note that `setState` is async so console.log will not get the just-updated value
console.log(coords) // {}
console.log(item) // {lat:...,lon:...}
const resNonJson2 = await apiGet(
`/data/2.5/onecall?lat=${item.lat}&lon=${item.lon}&exclude=current,alerts`
)
const resJson2 = await resNonJson2.json())
setForecast(resJson2);
}
}
... (other codes that I trust you do correctly)
return <div>
<pre>{JSON.stringify(coords)}</pre>
</div>
,
setState() 操作在 React 中是异步的。所有这一切都意味着您不能依赖在 setState 中应用的新状态值立即应用。 与 setState 一起,fetch() 本质上也是异步的。因此,console.log 语句不会等待 setState() 或 fetch() 执行。在这种情况下,你总是可以通过 setState() 的回调参数来处理它。
await apiGet(`/geo/1.0/direct?q=${city}`)
.then(r => r.json())
.then(r => setCoords(data => {lat: r[0].lat,lon:r[0].lon}))
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。