我正在使用天氣 api 來獲取最新的天氣結果,我有一個組件 Main 在里面,我正在渲染 RealTimeWeather 和 DayDetails 組件。我已將獲取的資料的結果設定為狀態物件,因此當它被接收時,Main 應該重新渲染,如您所見,
import React from "react";
import styled from "styled-components";
// import { realtime_weather } from "../data";
import RealTimeWeather from "./RealTimeWeather";
import DayDetails from "./DayDetails";
const MainArea = styled.div`
color: #fff;
letter-spacing: 0.6px;
word-spacing: 3px;
max-width: 1235px;
font-family: "Spline Sans", sans-serif;
font-weight: 300;
margin: auto;
`;
class Main extends React.Component {
constructor(props) {
super(props);
this.state = {};
}
componentDidMount() {
window.navigator.geolocation.getCurrentPosition(
(location) => {
fetch(
`https://api.weatherapi.com/v1/current.json?key=api_key&q=${location.coords.latitude},${location.coords.longitude}&aqi=yes`
)
.then((response) => response.json())
.then((data) => {
this.setState(data, function () {
this.forceUpdate();
});
});
},
(err) => {
console.log(err);
},
{ enableHighAccuracy: true }
);
}
render() {
return (
<MainArea>
<RealTimeWeather realtime_weather={this.state} />
<DayDetails realtime_weather={this.state} />
</MainArea>
);
}
}
export default Main;
這是實時天氣,
import React, { useState } from "react";
import styled from "styled-components";
const RealTimeWeatherContainer = styled.div`
text-align: center;
`;
const Location = styled.div`
font-size: 1.5625em;
`;
const Temperature = styled.div`
display: flex;
justify-content: center;
align-items: center;
gap: 10px;
`;
const TemperatureIcon = styled.img`
width: 70px;
`;
const TemperatureValue = styled.div`
font-size: 4.6875em;
`;
const DegreeSymbol = styled.span``;
const TemperatureUnitSwitcher = styled.div`
font-size: 1.5625em;
`;
const SelectedUnit = styled.div``;
const OtherUnit = styled.div`
margin-top: 2px;
color: #dbdde9;
&:hover {
border: 1px solid;
background: rgb(255, 255, 255, 0.2);
}
`;
const TemperatureText = styled.div`
font-size: 1.5625em;
margin: 18px 0px;
`;
const LastUpdated = styled.div`
margin-bottom: 15px;
font-size: 0.9375em;
`;
const Extras = styled.div`
display: flex;
justify-content: center;
align-items: center;
font-size: 0.9375em;
gap: 20px;
margin-bottom: 15px;
`;
const Extra = styled.div``;
function RealTimeWeather(props) {
const [currentUnit, changeCurrentUnit] = useState("C");
function toTime(unixTimeString) {
let time = new Date(unixTimeString * 1000);
let time_string = `${time.getHours()}:${time.getMinutes()}`;
return time_string;
}
function changeUnit() {
if (currentUnit === "C") {
changeCurrentUnit("F");
return;
}
changeCurrentUnit("C");
}
return (
<RealTimeWeatherContainer>
<Location>
{props.location.name}, {props.location.country}
</Location>
<Temperature>
<TemperatureIcon src={"https://ratentoi.sirv.com/sunny.svg"} />
<TemperatureValue>
{currentUnit === "C"
? Math.trunc(props.current.temp_c)
: Math.trunc(props.current.temp_f)}
<DegreeSymbol>°</DegreeSymbol>
</TemperatureValue>
<TemperatureUnitSwitcher>
<SelectedUnit>{currentUnit}</SelectedUnit>
<OtherUnit onClick={changeUnit}>
{currentUnit === "C" ? "F" : "C"}
</OtherUnit>
</TemperatureUnitSwitcher>
</Temperature>
<TemperatureText>{props.current.condition.text}</TemperatureText>
<LastUpdated>
Updated as of {toTime(props.current.last_updated_epoch)}
</LastUpdated>
<Extras>
<Extra>
Feels Like{" "}
{currentUnit === "C"
? Math.trunc(props.current.feelslike_c)
: Math.trunc(props.current.feelslike_f)}
<DegreeSymbol>°</DegreeSymbol>
</Extra>
<Extra>Wind {props.current.wind_kph} km/h</Extra>
<Extra>Visibility {props.current.vis_km} km</Extra>
</Extras>
<Extras>
<Extra>Barometer {props.current.pressure_mb} mb</Extra>
<Extra>Humidity {props.current.humidity}%</Extra>
<Extra>Dew Point</Extra>
</Extras>
</RealTimeWeatherContainer>
);
}
export default RealTimeWeather;
這是DayDetail,
import React from "react";
import styled from "styled-components";
// import { realtime_weather } from "../data";
const DayDetailsContainer = styled.div``;
const DayDetailsHeading = styled.div`
font-size: 25px;
margin-bottom: 20px;
`;
const DayDetailsContent = styled.div`
display: grid;
grid-template-columns: repeat(4, 1fr);
grid-template-rows: repeat(2, 1fr);
grid-gap: 25px;
`;
const DayDetail = styled.div`
width: 290px;
border-top: 1px solid #8190b5;
padding-top: 15px;
display: flex;
flex-direction: column;
gap: 15px;
font-size: 15px;
`;
const DayDetailText = styled.div``;
const DayDetailTextHeading = styled.div`
margin-bottom: 10px;
`;
const DayDetailTextContent = styled.div`
display: flex;
align-items: center;
gap: 12px;
font-size: 20px;
`;
const DayDetailTextContentLogo = styled.img`
width: 50px;
`;
const DayDetailTextContentDesc = styled.div``;
function DayDetails(props) {
return (
<DayDetailsContainer>
<DayDetailsHeading>Day Details</DayDetailsHeading>
<DayDetailsContent>
<DayDetail>
<DayDetailText>
<DayDetailTextHeading>Day</DayDetailTextHeading>
<DayDetailTextContent>Night Skies</DayDetailTextContent>
</DayDetailText>
<DayDetailText>
<DayDetailTextHeading>Night</DayDetailTextHeading>
<DayDetailTextContent>Night Skies</DayDetailTextContent>
</DayDetailText>
</DayDetail>
<DayDetail>
<DayDetailText>
<DayDetailTextHeading>Sunrise</DayDetailTextHeading>
<DayDetailTextContent>
<DayDetailTextContentLogo
src={
"https://ik.imagekit.io/dchud9yflpr/sunrise_bhQw0Iuzr.svg?updatedAt=1641230704341"
}
/>
<DayDetailTextContentDesc>
{
props.realtime_weather.forecast
.forecastday[0].astro.sunrise
}
</DayDetailTextContentDesc>
</DayDetailTextContent>
</DayDetailText>
<DayDetailText>
<DayDetailTextHeading>Sunset</DayDetailTextHeading>
<DayDetailTextContent>
<DayDetailTextContentLogo
src={
"https://ik.imagekit.io/dchud9yflpr/sunset_xmlFFk7th.svg?updatedAt=1641230704467"
}
/>
<DayDetailTextContentDesc>
{
props.realtime_weather.forecast
.forecastday[0].astro.sunset
}
</DayDetailTextContentDesc>
</DayDetailTextContent>
</DayDetailText>
</DayDetail>
<DayDetail>
<DayDetailText>
<DayDetailTextHeading>Moonrise</DayDetailTextHeading>
<DayDetailTextContent>
<DayDetailTextContentLogo
src={
"https://ik.imagekit.io/dchud9yflpr/sunrise_bhQw0Iuzr.svg?updatedAt=1641230704341"
}
/>
<DayDetailTextContentDesc>
{
props.realtime_weather.forecast
.forecastday[0].astro.moonrise
}
</DayDetailTextContentDesc>
</DayDetailTextContent>
</DayDetailText>
<DayDetailText>
<DayDetailTextHeading>Moonset</DayDetailTextHeading>
<DayDetailTextContent>
<DayDetailTextContentLogo
src={
"https://ik.imagekit.io/dchud9yflpr/sunset_xmlFFk7th.svg?updatedAt=1641230704467"
}
/>
<DayDetailTextContentDesc>
{
props.realtime_weather.forecast
.forecastday[0].astro.moonset
}
</DayDetailTextContentDesc>
</DayDetailTextContent>
</DayDetailText>
<DayDetailText>
<DayDetailTextHeading>Moon Phase</DayDetailTextHeading>
<DayDetailTextContent>
<DayDetailTextContentLogo
src={
"https://ik.imagekit.io/dchud9yflpr/sunset_xmlFFk7th.svg?updatedAt=1641230704467"
}
/>
</DayDetailTextContent>
</DayDetailText>
<DayDetailText>
<DayDetailTextHeading>
{
props.realtime_weather.forecast.forecastday[0]
.astro.moon_phase
}
</DayDetailTextHeading>
</DayDetailText>
</DayDetail>
<DayDetail></DayDetail>
<DayDetail></DayDetail>
<DayDetail></DayDetail>
</DayDetailsContent>
</DayDetailsContainer>
);
}
export default DayDetails;
這是錯誤,


這段代碼有什么問題?
uj5u.com熱心網友回復:
您必須添加條件,因為默認情況下您的狀態為空,并且在子組件中您使用undefined. 你也可以error從api獲取。
<MainArea>
{Object.keys(this.state).length &&
!this.state.error ? (
<div>
<RealTimeWeather realtime_weather={this.state} />
<DayDetails realtime_weather={this.state} />
</div>
) : (
<div>{JSON.stringify(this.state)}</div>
)}
</MainArea>
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/403131.html
標籤:
上一篇:從多個API端點獲取資料
