我试图创建一个简单的天气网络应用程序使用一个api,其中包含一个输入表单,以搜索城市和信息显示。我希望使用useEffect挂钩将默认城市设置为特定城市。因此,一旦用户打开应用程序,有关城市天气的信息就会显示出来。但是,它返回一个错误,表明数据不存在。
这是我的App.js文件
import React, { useState, useEffect } from 'react'
import Search from './components/Search.js'
import './App.scss';
function App() {
const [city, setCity] = useState('London')
const [unit, setUnit] = useState('metric')
const [info, setInfo] = useState({})
const key = process.env.REACT_APP_WEATHER_API_KEY
const api = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${key}&units=${unit}`
useEffect(() => {
fetch(api)
.then(res => {
if (!res.ok){
throw Error('could not fetch the data')
}
return res.json()
})
.then(data => {
setInfo(data)
console.log(data)
})
.catch(err => console.log(err.message))
}, [city])
return (
<div className="app">
<Search setCity={setCity}/>
<h1 className='city'>{city}</h1>
<h2 className='temperature'>Temperature: {info.main.temp}</h2>
</div>
);
}
export default App;Search.js文件
import React from 'react'
function Search({setCity}) {
const search = (e) => {
const loc = e.target.value.trim().replace(/^\w/, (c) => c.toUpperCase())
if (e.key === 'Enter' && loc !== ''){
setCity(loc)
}
}
return (
<div className='search-container'>
<input type="text" onKeyPress={search} defaultValue='London'/>
</div>
)
}
export default Search错误消息
Uncaught TypeError: Cannot read properties of undefined (reading 'temp')似乎发生了错误,因为我试图访问h2标记中的温度信息(H2)。但是,如果我删除它,一切都将正常工作,并且信息仍将从api中检索。
发布于 2022-04-04 07:02:30
你已经将info初始化为一个空对象-
const [info, setInfo] = useState({})当您的组件第一次呈现时,info对象上没有info属性(因为它是空的),因此此调用将始终失败,出现您正在看到的错误:
<h2 className='temperature'>Temperature: {info.main.temp}</h2>要修复它,可以在使用可选链访问该属性之前检查该属性是否存在。
<h2 className='temperature'>Temperature: {info.main?.temp}</h2>发布于 2022-04-04 07:04:34
你的useEffect依赖于“城市”。在开始时,您试图在任何城市变化之前显示温度值。
要解决这个问题,您可以避免试图显示标记:
{info && <h2 className='temperature'>Temperature: {info.main.temp}</h2>}或者:
{info ? <h2 className='temperature'>Temperature: {info.main.temp}</h2> : <Loading/>}在这种情况下,不需要将默认值设置为"info“useState。
const [info, setInfo] = useState()发布于 2022-04-04 07:06:41
如果您检查info.main不是未定义的,然后呈现出来,那就更好了。
import React, { useState, useEffect } from 'react'
import Search from './components/Search.js'
import './App.scss';
function App() {
const [city, setCity] = useState('London')
const [unit, setUnit] = useState('metric')
const [info, setInfo] = useState({})
const key = process.env.REACT_APP_WEATHER_API_KEY
const api = `https://api.openweathermap.org/data/2.5/weather?q=${city}&appid=${key}&units=${unit}`
useEffect(() => {
fetch(api)
.then(res => {
if (!res.ok){
throw Error('could not fetch the data')
}
return res.json()
})
.then(data => {
setInfo(data)
console.log(data)
})
.catch(err => console.log(err.message))
}, [city])
return (
<div className="app">
<Search setCity={setCity}/>
<h1 className='city'>{city}</h1>
{info.main ? (
<h2 className='temperature'>Temperature: {info.main.temp}</h2>
) : (
<h2 className='loading'>Loading...</h2>
)}
</div>
);
}
export default App;https://stackoverflow.com/questions/71733044
复制相似问题