获取数据,获取对象,但仍然有错误。未捕获(在承诺中)类型错误:无法读取未定义的属性(读取"0")



无法修复此错误。我通过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

在此处输入图像描述

在用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;

最新更新