我试图做的是从天气API获取数据,但是在第一次渲染时,"data"状态为空,在第二次渲染时,调用API并设置数据。这使得当我稍后尝试访问图像的数据时,我会收到错误,TypeError: Cannot read property 'weather' of undefined
,因为它最初是空的。不知何故,我需要跟踪渲染发生的次数或更改我获取数据的方式。我认为useEffect
将空列表作为第二个参数将充当componentDidMount
.这是我的代码:
import React, {useState, useEffect} from 'react';
export default function App() {
const useFetch = () =>{
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect( () => {
async function fetchData(){
const response = await fetch('https://api.weatherbit.io/v2.0/forecast/hourly?city=Chicago,IL&key=XXX&hours=24');
const json = await response.json();
setData(json.data);
setLoading(false);
}
fetchData();
}, []);
return {data, loading};
}
const convert = (c) =>{
let f = (c*(9/5))+32;
return f
}
const {data, loading} = useFetch();
console.log(data)
return (
<div>
<img src={'https://www.weatherbit.io/static/img/icons/'+data[0].weather.icon+'.png'}/>
<h1>{loading ? 'Loading...' : ''}</h1>
</div>
)
}
传递给useEffect
的函数将在渲染提交到屏幕后运行,默认情况下,效果在每次完成渲染后运行。您只需要在 api 调用完成时渲染img
,即加载false
时。
import React, {useState, useEffect} from 'react';
export default function App() {
const useFetch = () =>{
const [data, setData] = useState([]);
const [loading, setLoading] = useState(true);
useEffect( () => {
async function fetchData(){
const response = await fetch('https://api.weatherbit.io/v2.0/forecast/hourly?city=Chicago,IL&key=XXX&hours=24');
const json = await response.json();
setData(json.data);
setLoading(false);
}
fetchData();
}, []);
return {data, loading};
}
const convert = (c) =>{
let f = (c*(9/5))+32;
return f
}
const {data, loading} = useFetch();
if(loading) {
return <h1>{'Loading...'}</h1>
}
return (
<div>
<img src = {'https://www.weatherbit.io/static/img/icons/'+data[0].weather.icon+'.png'}/>
</div>
)
}
你可以试试这样的东西
const [data, setData] = useState(null);
return (
{data ? ( <div>
<img src={'https://www.weatherbit.io/static/img/icons/'+data[0].weather.icon+'.png'}/>
<h1>{loading ? 'Loading...' : ''}</h1>
</div>) : <p>Loading....<p>}
)
这会在第一次渲染时将数据设置为 null,渲染函数中的条件渲染会检查数据是否为 true/或有数据,如果没有,则返回加载...发短信
你可以在渲染函数中放一个条件
return (
<div>
{data && data.weather && <img src={'https://www.weatherbit.io/static/img/icons/'+data[0].weather.icon+'.png'}/>}
<h1>{loading ? 'Loading...' : ''}</h1>
</div>
)