获取数据,获取对象,但仍有错误。未捕获(在承诺中)TypeError:无法读取未定义的属性(读取“0”)
2022-09-03
819
无法修复此错误。 我通过 fetch 方法从 thingspeak.com 接收数据(对象)。然后我想从该对象呈现三个值:名称、温度和时间。我可以看到温度和名称,但看不到时间。 这是我在控制台中的错误: 未捕获(在承诺中)TypeError:无法读取未定义的属性(读取“0”)。 有什么想法吗?
import React, { useState, useEffect } from 'react'
const App = () => {
const [channelInfo, setChannelInfo] = useState({});
const [isLoading, setIsLoading] = useState(true);
const [dateWithOffset, setDateWithOffset] = useState(null);
const getThermoData = async () => {
setIsLoading(true);
const response = await fetch(`https://api.thingspeak.com/channels/618304/fields/1.json?results=1`);
const data = await response.json();
setChannelInfo(data);
setIsLoading(false);
timeConverter();
}
const timeConverter = () => {
const channelDate = channelInfo.feeds[0].created_at;
const date = new Date(channelDate);
const timestampWithOffset = date.getTime();
setDateWithOffset(new Date(timestampWithOffset));
}
useEffect(() => {
getThermoData();
}, [])
return (
<div className='card'>
{
isLoading ? <p className='loading'>Loading...</p> : <>
<h5 className='channel-name no-select'>{channelInfo.channel.name}</h5>
<p className='temperature-value no-select'>{channelInfo.feeds[0].field1}</p>
<h5 className='channel-time no-select'>{dateWithOffset}</h5>
</>
}
</div>
)
}
export default App
1个回答
在使用
setChannelInfo(data);
设置新状态后立即调用
timeConverter
将引发异常,因为 1) 初始
channelInfo
值为
{},因此没有
.feeds[0].created_at
和 2) 调用
setChannelInfo
不会立即更新变量。它只会在下次渲染时更新。
您可以切换到
useMemo
,添加
undefined
检查,将
channelInfo
的初始状态更改为未定义。
import { useState, useEffect, useMemo } from "react";
const App = () => {
const [channelInfo, setChannelInfo] = useState();
const [isLoading, setIsLoading] = useState(true);
const dateWithOffset = useMemo(() => {
if (!channelInfo) return "";
const channelDate = channelInfo.feeds[0].created_at;
const date = new Date(channelDate);
const timestampWithOffset = date.getTime();
return new Date(timestampWithOffset).toString();
}, [channelInfo]);
const getThermoData = async () => {
setIsLoading(true);
const response = await fetch(
`https://api.thingspeak.com/channels/618304/fields/1.json?results=1`
);
const data = await response.json();
setChannelInfo(data);
setIsLoading(false);
};
useEffect(() => {
getThermoData();
}, []);
return (
<div className="card">
{isLoading ? (
<p className="loading">Loading...</p>
) : (
<>
<h5 className="channel-name no-select">{channelInfo.channel.name}</h5>
<p className="temperature-value no-select">
{channelInfo.feeds[0].field1}
</p>
<h5 className="channel-time no-select">{dateWithOffset}</h5>
</>
)}
</div>
);
};
export default App;
Sergey Sosunov
2022-09-03