javascript - 从 React 应用程序中的 api 获取数据之前的页面渲染导致错误
问题描述
我正在为导航使用以下组件。在这个导航栏上,我想显示用户当前位置的天气。唯一的问题是页面在从 openWeather api 获取数据之前正在渲染。
import React, { useState, useEffect } from 'react';
const api = {
key: "mykey",
base: "https://api.openweathermap.org/data/2.5/"
}
const Nav = () => {
useEffect(() => {
const successfulLookup = position => {
const { latitude, longitude } = position.coords;
fetch(`https://api.opencagedata.com/geocode/v1/json?q=${latitude}+${longitude}&key=mykey`)
.then(response => response.json())
.then(result => {
const query = result.results[0].components.city;
weatherOnLoad(query);
})
};
const weatherOnLoad = query => {
fetch(`${api.base}weather?q=${query}&units=metric&APPID=${api.key}`)
.then(res => res.json())
.then(result => {
setWeather(result);
console.log(result);
});
};
// successfulLookup();
if (window.navigator.geolocation) {
window.navigator.geolocation
.getCurrentPosition(successfulLookup, console.log);
}
}, []);
const [weather, setWeather] = useState({});
const dateBuilder = (d) => {
let months = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
let days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
let day = days[d.getDay()];
let date = d.getDate();
let month = months[d.getMonth()];
let year = d.getFullYear();
return `${month} ${date}, ${year} | ${day}`
}
return (
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<a className="navbar-brand" href="/#">Get-Set-Note</a>
<div className="date">{dateBuilder(new Date())}</div>
<div className="temp">
{Math.round(weather.main.temp)}°c
</div>
</nav>
);
};
export default Nav;
因此,我收到此错误:
TypeError: Cannot read property 'temp' of undefined
如何解决这个问题?
解决方案
weather
在拥有它之前不要尝试访问:
{weather && weather.main ? <div className="temp">{Math.round(weather.main.temp)}°c</div> : null}
顺便说一句,这里有一种更惯用的方式来编写代码,使用更少的嵌套函数和更多async
/await
来减少嵌套。
import React, { useState, useEffect } from "react";
const api = {
key: "mykey",
base: "https://api.openweathermap.org/data/2.5/",
};
const months = [
"January",
"February",
"March",
"April",
"May",
"June",
"July",
"August",
"September",
"October",
"November",
"December",
];
const days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
function formatDate(d) {
const day = days[d.getDay()];
const date = d.getDate();
const month = months[d.getMonth()];
const year = d.getFullYear();
return `${month} ${date}, ${year} | ${day}`;
}
async function getWeatherForCoordinates(latitude, longitude) {
const cityResp = await fetch(`https://api.opencagedata.com/geocode/v1/json?q=${latitude}+${longitude}&key=mykey`);
const result = await cityResp.json();
const query = result.results[0].components.city;
const weatherResp = await fetch(`${api.base}weather?q=${query}&units=metric&APPID=${api.key}`);
const weather = await weatherResp.json();
return weather;
}
// Promisified `geolocation.getCurrentPosition`
async function getCurrentPositionP() {
return new Promise((resolve, reject) => {
if (!window.navigator.geolocation) {
return reject("No geolocation");
}
window.navigator.geolocation.getCurrentPosition(resolve, reject);
});
}
async function getLocalWeather() {
const position = await getCurrentPositionP();
const { latitude, longitude } = position.coords;
const weather = await getWeatherForCoordinates(latitude, longitude);
return weather;
}
const Nav = () => {
const [weather, setWeather] = useState(null);
useEffect(() => {
getLocalWeather().then(setWeather, console.error);
}, []);
return (
<nav className="navbar navbar-expand-lg navbar-light bg-light">
<a className="navbar-brand" href="/#">
Get-Set-Note
</a>
<div className="date">{formatDate(new Date())}</div>
{weather ? <div className="temp">{Math.round(weather.main.temp)}°c</div> : null}
</nav>
);
};
export default Nav;
推荐阅读
- kubernetes - ReplicaSet 不会删除 Replication Controller pod?
- javascript - React Javascript,从现有的数组中创建新的数组
- c++ - 编译后的代码不执行文件写入
- python - Python:使用自定义指标生成 Voronoi 细分
- excel - Excel:查找从购买之日起库存的存货时间以及范围
- matlab - 带 e 的 Matlab 数
- java - 当组 DN 名称上有斜杠时,无法使用 ldap api 将用户添加到组
- python - 为什么在对元组进行排序时,我得到一个列表作为 sorted() 函数的最终输出?
- layout - 无法使用 Nebular NbLayoutComponent 在整个可用屏幕上显示页面内容
- python - 我想计算特定项目的数量