找不到我的应用返回 Uncaught TypeError: Cannot read properties of undefined 的原因
2023-04-14
96
我正在使用 useState 来存储从 api 返回的数据:
function App() {
const [{ ipAddressData, shouldLoadItems }, setModel] = useState<AppState>({
ipAddressData: [],
shouldLoadItems: true,
});
const [ipAddress, setIpAddress] = useState("");
const ipDataUrl = `https://geo.ipify.org/${ipAddress}`;
useEffect(() => {
const fetchData = async () => {
const response = await fetch(ipDataUrl);
const data: IpAddress[] = await response.json();
setModel({
ipAddressData: data,
shouldLoadItems: false,
});
};
if (shouldLoadItems) {
fetchData();
}
}, [shouldLoadItems]);
function inputIp(e: { preventDefault: () => void }) {
setModel((prevState) => {
return {
...prevState,
shouldLoadItems: true,
};
});
e.preventDefault();
}
然后我尝试返回数据,但出现以下错误: Uncaught TypeError:无法读取未定义的属性
const { ip, location, domains, as, isp }: IpAddressData = ipAddressData;
return (
<div className="App">
<main className={mainCss}>
<h1 className={mainTitleCss}>IP Address Tracker</h1>
<form className={searchBarContainerCss} onSubmit={inputIp}>
<input
type="text"
placeholder="Search for any IP address or domain"
className={searchInputCss}
onChange={(e) => setIpAddress(e.target.value)}
/>
<input type="submit" value="" className={searchBarButtonCss} />
</form>
<Results
ip={ip}
location={getLocation(
location.city,
location.country,
location.postalCode
)}
timezone={location.timezone}
isp={isp}
/>
function getLocation(city: string, country: string, postalCode: string) {
return `${city}, ${country} ${postalCode}`;
}
Results.tsx:
interface IpAddressProps {
ip: string;
location: string;
timezone: string;
isp: string;
}
const Results: FC<IpAddressProps> = ({ ip, location, timezone, isp }) => {
return (
<div className={resultsContainerCss}>
<div className={resultCss}>
<div className={resultTitleCss}>IP Address</div>
<div className={resultInfoCss}>{ip}</div>
</div>
<div className={resultCss}>
<div className={resultTitleCss}>Location</div>
<div className={resultInfoCss}>{location}</div>
</div>
<div className={resultCss}>
<div className={resultTitleCss}>Timezone</div>
<div className={resultInfoCss}>UTC {timezone}</div>
</div>
<div className={resultCss}>
<div className={resultTitleCss}>ISP</div>
<div className={resultInfoCss}>{isp}</div>
</div>
</div>
);
};
export default Results;
存储我的接口的 index.ts:
interface Location {
country: string;
region: string;
city: string;
lat: number;
lng: number;
postalCode: string;
timezone: string;
geonameId: number;
}
interface As {
asn: number;
name: string;
route: string;
domain: string;
type: string;
}
export interface IpAddressData {
ip: string;
location: Location;
domains: string[];
as: As;
isp: string;
}
export interface IpAddress {
data: IpAddressData;
}
当我 console.log ipAddressData 时,它会按预期从 api 返回数据,所以我不知道问题是什么
2个回答
首先,这两段代码是相互冲突的。
const [{ ipAddressData, shouldLoadItems }, setModel] = useState<AppState>({
ipAddressData: [],
shouldLoadItems: true,
});
setModel({
ipAddressData: data,
shouldLoadItems: false,
});
您的
useState
数组中有一个名为
ipAddressData
的变量,
setModel
中也有一个名为
ipAddressData
的变量。如果您将鼠标悬停在
setModel
调用中的
ipAddressData
上。它会说
ipAddressData
不可分配。
我建议将
useState
返回的第一个变量名称更改为如下所示:
const [data, setModel] = useState<AppState>({
ipAddressData: [],
shouldLoadItems: true,
});
这样当您调用时:
setModel({
ipAddressData: data,
shouldLoadItems: false,
});
它不是说
ipAddressData
不可分配。
稍后,如果您想引用
ipAddressData
或
shouldLoadItems
值。您可以像
data.ipAddressData
或
data.shouldLoadItems
那样调用它。
之后,看看您的错误
Uncaught TypeError
是否消失。
Khairani F
2023-04-14
我发现错误,
AppState
接口将
ipAddressData
定义为一个数组,而实际上它应该是一个对象,这就是它返回未定义的原因。
interface AppState {
ipAddressData: IpAddressData[];
shouldLoadItems: boolean;
}
应该是这个:
interface AppState {
ipAddress: IpAddress | undefined;
shouldLoadItems: boolean;
}
Alex
2023-04-14