在 useEffect 中设置状态然后访问其属性
2020-07-21
553
我尝试访问我的状态下使用 React 中的 useEffect 钩子设置的属性,但我一直收到此错误 Uncaught “TypeError:无法读取未定义的属性‘0’” 。 这是我的代码:-
import React, { useState, useEffect } from "react";
const Geocode = (props) => {
const [location, setLocation] = useState([]);
useEffect(() => {
async function fetchData() {
const response = await fetch(
`https://eu1.locationiq.com/v1/search.php?key=MY_KEY=${props.address}&format=json&limit=1`
);
const data = await response.json();
setLocation((location) => ({ ...location, data }));
}
fetchData();
}, [props.address]);
const latitude = location.data[0].lat;
const longitude = location.data[0].lon;
return (
<div>
<h2>Location</h2>
{location && (
<p>
Lat: {latitude}, Lon: {longitude}
</p>
)}
</div>
);
};
export default Geocode;
以下 API 调用的输出是:-
[{…}]
0:
boundingbox: (4) ["-1.444471", "-1.163332", "36.6509378", "37.1038871"]
class: "place"
display_name: "Nairobi, Kenya"
icon: "https://locationiq.org/static/images/mapicons/poi_place_city.p.20.png"
importance: 0.73502675943376
lat: "-1.2832533"
licence: "https://locationiq.com/attribution"
lon: "36.8172449"
osm_id: "9185096"
osm_type: "relation"
place_id: "237011109"
type: "city"
__proto__: Object
length: 1
__proto__: Array(0)
2个回答
useEffect
在组件在 dom 中呈现后执行。因此,当初始加载组件时,它会获取
location
默认值作为
[]
。因此,当它访问
data
属性时,它会变得未定义并引发错误。解决此问题的最佳方法是检查
location
是否具有
data
属性。您可以通过两种方式做到这一点:
1.可选链接
const latitude = location?.data?.[0]?.lat;
const longitude = location?.data?.[0]?.lon;
您可以在此处阅读有关它的更多信息 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Optional_chaining 。
2. 条件检查
const latitude = location.data && location.data.length > 0 ?location.data.[0].lat: 0;
const longitude = location.data && location.data.length > 0 ? location.data.[0].lon : 0;
此外,我建议将默认值分配给
location
作为空对象
{},因为您为其分配了一个对象而不是数组。这将使代码更不容易出错。
Pranay Tripathi
2020-07-22
该行
const latitude = location.data[0].lat;
正在抛出错误,因为在
useEffect
有机会获取和填充数据之前,您正在尝试访问它。
您正在使用
{location && (...)
在 JSX 中防止该错误,因此无需在外部定义纬度和经度,只需将计算结果放在其中即可。
此外,您应该标准化
location
状态的类型?首次定义它时,您将默认值设置为列表
[]
,但是当您更新它时,您会创建一个对象
{
。
Luke Storry
2020-07-22