我有这个 react 组件,每次渲染时都会显示通过道具(国家/地区)接收的国家/地区信息,并且使用天气堆栈 API 还必须显示当前时间的首都天气。第一部分(显示来自道具的国家数据)工作正常,但我正在努力从天气 API 获取数据。我在控制台上看到我正在获取当前天气,但无法使用 setState() 将其分配给天气变量,因此我的应用程序崩溃了。
这是我到目前为止的组件代码,我尝试使用 async/await
和 .then
语法以防我拼写错误,但总是得到相同的结果:
const CountryDetails = async ({country}) => {
const [weather, setWeather] = useState({});
// const hook = async () => {
// const result = await axios.get(`http://api.weatherstack.com/current?access_key=${WEATHER_API}&query=${country.capital}`);
// console.log(result.data);
// setWeather(result.data.current);
// console.log(weather);
// }
const hook = () => {
axios.get(`http://api.weatherstack.com/current?access_key=${WEATHER_API}&query=${country.capital}`).then((response) => {
console.log('then');
setWeather({
temperature: response.data.current.temperature,
img: response.data.current.weather_icons,
wind: response.data.current.wind_speed,
dir: response.data.current.wind_direction
});
console.log(response.data.current);
});
}
useEffect(hook, []);
console.log(weather);
return (
<>
<h1>{country.name}</h1>
<p>capital {country.capital}</p>
<p>population {country.population}</p>
<h2>languages</h2>
<ul>
{country.languages.map((lang) => {
<li key={lang.name}>{lang.name}</li>;
})}
</ul>
<img src={country.flag}></img>
<h2>Weather in {country.capital}</h2>
<p><b>temperature: </b>{weather.current.temperature}</p>
<img src={weather.current.weather_icons} />
<p><b>wind: </b>{weather.current.wind_speed} direction {weather.current.wind_direction}</p>
</>
);
};
答案 0 :(得分:1)
这是我用你的代码创建的一个代码沙盒。既然你说你成功地从 API 接收数据,我用我的 getWeather
函数来嘲笑它。除了@Viet 的回答之外,您提供的代码中还有其他问题。看看这是否有帮助或错误仍然存在,请提供代码片段的复制示例:
https://codesandbox.io/s/competent-dhawan-fds81?file=/src/App.js:52-62
import { useEffect, useState } from "react";
const getWeather = (country) => {
return Promise.resolve({
data: {
current: {
temperature: "<temperature>",
weather_icons: "<weather_icons>",
wind_speed: "<wind_speed>",
dir: "<wind_direction>"
}
}
});
};
const CountryDetails = ({ country }) => {
const [weather, setWeather] = useState({});
const hook = () => {
getWeather(country).then((response) => {
console.log("then");
setWeather({
temperature: response.data.current.temperature,
img: response.data.current.weather_icons,
wind: response.data.current.wind_speed,
dir: response.data.current.dir,
wind_speed: response.data.current.wind_speed
});
console.log(response.data.current);
});
};
useEffect(hook, [country]);
// You should get {} logged here, not undefined
console.log(weather);
return (
<>
<h1>{country.name}</h1>
<p>Capital: {country.capital}</p>
<p>Population: {country.population}</p>
<h2>Languages</h2>
<ul>
{/* You were not returning anything in the callback of the map function */}
{country.languages.map((lang, i) => (
<li key={i}>{lang.name}</li>
))}
</ul>
<img src={country.flag}></img>
<h2>Weather in {country.capital}</h2>
<p>
<b>temperature: </b>
{/* As @Veit mentioned, you were accessing the wrong property */}
{weather.temperature}
</p>
<img src={weather.weather_icons} />
<p>
<b>Wind: </b>
{weather.wind_speed} Direction: {weather.dir}
</p>
</>
);
};
export default (props) => {
const country = {
languages: [{ name: "<name>" }],
flag: "<flag name>",
capital: "<capital name>",
name: "<Coutry Name>",
population: "<POPULATION>"
};
return <CountryDetails country={country} />;
};
答案 1 :(得分:0)
您只是从天气状态中提取了错误的属性。这有效:
import axios from "axios";
import { useState, useEffect } from "react";
const WEATHER_API = "xxx";
const CountryDetails = ({ country }) => {
const [weather, setWeather] = useState({});
const hook = () => {
axios
.get(
`http://api.weatherstack.com/current?access_key=${WEATHER_API}&query=${country.capital}`
)
.then((response) => {
console.log("then", response);
setWeather({
temperature: response.data.current.temperature,
img: response.data.current.weather_icons,
wind: response.data.current.wind_speed,
dir: response.data.current.wind_dir
});
console.log(JSON.stringify(weather));
});
};
useEffect(hook, []);
console.log(weather);
return (
<>
<h2>languages</h2>
<p><b>temperature: </b>{weather.temperature}</p>
<p>
<b>wind: </b>
{weather.wind} direction {weather.dir}
</p>
</>
);
};
export default function App() {
return (
<div className="App">
<CountryDetails country={{ capital: "London" }} />
</div>
);
}