React 无法更新状态 [英] React cannot update state
问题描述
我不明白为什么我不能更新我的状态(参见 setCoords).请求返回 200 代码,并且我尝试检索的元素存在:
这是我的代码:
const App = () =>{const [city, setCity] = useState("");const [forecast, setForecast] = useState(null);const [coords, setCoords] = useState({});const handleSearchChange = ev =>{设置城市(ev.target.value);};异步函数 onSearch() {如果(城市){等待 apiGet(`/geo/1.0/direct?q=${city}`).then(r => r.json()).then(r => setCoords({lat: r[0].lat, lon:r[0].lon}));//不设置任何东西await console.log(coords)//控制台日志 {}等待 apiGet(`/data/2.5/onecall?lat=${coords.lat}&lon=${coords.lon}&exclude=current,minutely,hourly,alerts`).then(r => r.json()).then(r => setForecast(r));}}
感谢您的帮助!
需要注意的一点是不要将 await
与 then
混用(更多相关信息:可以等待然后混合在一个实现中吗?).由于您使用的是 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(城市",城市,预测",预报,坐标",坐标);const handleSearchChange = ev =>{设置城市(ev.target.value);};异步函数 onSearch() {如果(城市){const resNonJson = await apiGet(`/geo/1.0/direct?q=${city}`)const resJson = 等待 resNonJson.json())const item = resJson[0];setCoords({lat: item.lat, lon: item.lon}));//注意`setState` 是异步的,所以console.log 不会得到刚刚更新的值控制台日志(坐标)//{}console.log(item)//{lat:..., lon:...}const resNonJson2 = 等待 apiGet(`/data/2.5/onecall?lat=${item.lat}&lon=${item.lon}&exclude=current,minutely,hourly,alerts`)const resJson2 = 等待 resNonJson2.json())设置预测(resJson2);}}...(我相信你做的其他代码是正确的)返回 <pre>{JSON.stringify(coords)}</pre>
I can't figure why I can't update my state (see setCoords). The request returns with a 200 code and the elements I'm trying to retrieve exists :
Here is my code :
const App = () => {
const [city, setCity] = useState("");
const [forecast, setForecast] = useState(null);
const [coords, setCoords] = useState({});
const handleSearchChange = ev => {
setCity(ev.target.value);
};
async function onSearch() {
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));
}
}
Thanks for your help!
One thing to note is that don't mix await
with then
(More on this: Can await and then be mixed in one implementation?). Since you are using async
, I recommend you change all to await
, like below
Another thing to note is setStates
calls (i.e setCoords
and setForecast
and setCity
) is asynchronous by nature, meaning that an immediate console.log
after setting state will not log the just-updated value. Instead, React will schedule those setState onto the next render - therefore, you can only see/access the most updated values in the next render cycle. If you want to log values, you can put them as inside a <pre>
tag in your HTML, or do console.log
at the beginning, like below:
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,minutely,hourly,alerts`
)
const resJson2 = await resNonJson2.json())
setForecast(resJson2);
}
}
... (other codes that I trust you do correctly)
return <div>
<pre>{JSON.stringify(coords)}</pre>
</div>
这篇关于React 无法更新状态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!