gpt4 book ai didi

javascript - useState 变量在 useEffect API 调用之前调用

转载 作者:行者123 更新时间:2023-12-02 18:37:40 25 4
gpt4 key购买 nike

据我了解 useEffect 钩子(Hook)最后作为 sideEffect 运行。我正在尝试控制台日志data.main.temp。我可以理解,它还不知道那是什么,因为它正在从之后运行的 useEffect Hook 中的 API 获取数据。

API 调用后如何访问或控制台日志 data.main.temp? (我觉得 setTimout 是一种作弊方式?)

import React, { useState, useEffect } from "react";
import Button from "../UI/Button";
import styles from "./Weather.module.css";
import moment from "moment";
import Card from "../UI/Card";

export default function Weather() {
//State Management//
const [lat, setLat] = useState([]);
const [long, setLong] = useState([]);
const [data, setData] = useState([]);

//openWeather API key
const key = "xxxxxxxxxxxxxxxxxxxxxxxxxx";

useEffect(() => {
const fetchData = async () => {
//get coordinates//
navigator.geolocation.getCurrentPosition(function (position) {
setLat(position.coords.latitude);
setLong(position.coords.longitude);
});
//fetch openWeather api//
await fetch(`https://api.openweathermap.org/data/2.5/weather/?lat=${lat}&lon=${long}&units=metric&APPID=${key}`)
.then((res) => res.json())
.then((result) => {
setData(result);
console.log(result);
});
};
fetchData();
}, [lat, long]);


//Examples of what I want, they run too early before api//
console.log(data.main.temp);
const Farenheit = data.main.temp * 1.8 + 32;

return (
<Card>
{typeof data.main != "undefined" ? (
<div className={`${styles.weatherContainer} ${styles.clouds}`}>
<h2>Weather</h2>
<p>{data.name}</p>
<p>{data.main.temp * 1.8 + 32} &deg;F</p>
<p>{data.weather[0].description}</p>
<hr></hr>
<h2>Date</h2>
<p>{moment().format("dddd")}</p>
<p>{moment().format("LL")}</p>
</div>
) : (
<div></div>
)}
</Card>
);
}

最佳答案

你是对的,效果函数在第一次渲染后运行,这意味着你需要以某种方式等待 api 调用完成。一种常见的方法是引入另一个状态标志来指示数据是否可用。

另一件不遵循 React 良好实践的事情是,你的效果函数不仅仅做一件事。

我还添加了简单的错误处理并清理了混合 promise 和异步等待

这是您重构的代码

import React, { useState, useEffect } from "react";
import Button from "../UI/Button";
import styles from "./Weather.module.css";
import moment from "moment";
import Card from "../UI/Card";

//openWeather API key
const key = "xxxxxxxxxxxxxxxxxxxxxxxxxx";

export default function Weather() {
//State Management//
const [lat, setLat] = useState();
const [long, setLong] = useState();
const [data, setData] = useState();
const [error, setError] = useState();
const [loading, setLoading] = useState(false);

useEffect(() => {
navigator.geolocation.getCurrentPosition((position) => {
setLat(position.coords.latitude);
setLong(position.coords.longitude);
});
}, []);

useEffect(() => {
const fetchData = async () => {
if (lat && long && key) {
try {
setLoading(true);
const response = await fetch(
`https://api.openweathermap.org/data/2.5/weather/?lat=${lat}&lon=${long}&units=metric&APPID=${key}`
);
const data = await response.json();
setData(data);
setLoading(false);
} catch (err) {
setError(err);
setLoading(false);
}
}
};
fetchData();
}, [lat, long]);

if (error) {
return <div>some error occurred...</div>;
}

return (
<Card>
{loading || !data ? (
<div>loading...</div>
) : (
<div className={`${styles.weatherContainer} ${styles.clouds}`}>
<h2>Weather</h2>
<p>{data.name}</p>
<p>{data.main.temp * 1.8 + 32} &deg;F</p>
<p>{data.weather[0].description}</p>
<hr></hr>
<h2>Date</h2>
<p>{moment().format("dddd")}</p>
<p>{moment().format("LL")}</p>
</div>
)}
</Card>
);
}


关于javascript - useState 变量在 useEffect API 调用之前调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68535552/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com