尝试每 3 秒或 30 秒刷新一次 Open Weather Api
2022-08-27
486
我根据 YouTube 视频创建了一个简单的天气网络应用,并希望它每 3 秒或 30 秒自动刷新一次,但是当我尝试使用
setInterval
时出现了无法识别的错误:
App.js:15 Uncaught TypeError: Cannot read properties of undefined (reading 'key') at search (App.js:15:1)
我刚刚开始使用 react-js,这是我的代码:
import './App.css';
import React, { useState } from 'react';
const api = {
key: "5f285d33be01b937453b7e1688fc75ee",
base:"https://api.openweathermap.org/data/2.5/"
}
function App() {
const [query, setQuery] = useState('');
const [weather, setWeather] = useState({});
const search = evt => {
if (evt.key === "Enter") {
fetch(`${api.base}weather?q=${query}&units=metric&APPID=${api.key}`)
.then(res => res.json())
.then(result => {
setWeather(result);
setQuery('');
console.log(result);
});
}
}
//
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 `${day} ${date} ${month} ${year}`
}
function round(value, precision) {
var multiplier = Math.pow(10, precision || 0);
return Math.round(value * multiplier) / multiplier;
}
return (
<div className={(typeof weather.main != "undefined")? ((weather.main.temp > 9) ? ((weather.weather[0].main == 'Rain')? 'app rain': ((weather.weather[0].main == 'Clouds')? 'app clouds': 'app warm')) : 'app'): 'app'}>
<main>
<div className='search-box'>
<input type="text" className='search-bar' placeholder='Search...' onChange={e => setQuery(e.target.value)} value={query} onKeyPress={search} />
</div>
{(typeof weather.main != "undefined") ? (
<div>
<div className='loaction-box'>
<div className='location'>
{weather.name}, {weather.sys.country}
</div>
<div className='date'>{dateBuilder(new Date())}</div>
<div className='weather-box'>
<div className='temp'>
{Math.round(weather.main.temp)}°c
<div className='weather-small'>
Humidity: {weather.main.humidity}%
<br/>
Wind: {round(weather.wind.speed,1)}km/h
</div>
<div className='weather-small'></div>
</div>
<div className='weather'>
{weather.weather[0].description}</div>
</div>
</div>
</div>
): ('')}
</main>
</div>
);
}
export default App;
2个回答
共享代码片段中没有
setInterval
,但根据代码和包含的错误消息,我假设您尝试将
search
作为间隔回调传递。
setInterval(search, 3000);
这里的问题是
search
需要传递
onKeyPress
事件对象。
const search = evt => {
if (evt.key === "Enter") { // <-- evt undefined
fetch(`${api.base}weather?q=${query}&units=metric&APPID=${api.key}`)
.then(res => res.json())
.then(result => {
setWeather(result);
setQuery('');
console.log(result);
});
}
}
我建议重构一下代码。从按键逻辑中分离出获取逻辑。创建一个
onKeyPress
处理程序,该处理程序调用
search
回调并传递
query
状态,并使用依赖于
query
状态的
useEffect
钩子来实例化间隔计时器。
示例:
const search = async (query) => {
try {
const res = await fetch(`${api.base}weather?q=${query}&units=metric&APPID=${api.key}`);
const result = await res.json();
setWeather(result);
console.log(result);
} catch (error) {
// catch & handle any Promise rejections and thrown errors
}
}
const keyPressHandler = async (evt) => {
if (evt.key === "Enter") {
await search(query);
setQuery('');
}
}
useEffect(() => {
let timer = null;
if (query) {
timer = setInterval(search, 3000, query);
}
return () => clearInterval(timer);
}, [query]);
Drew Reese
2022-08-28
将 onKeyPress 更改为 onKeyDown 并且其事件具有 key 属性
n1koloza
2022-08-27