React 无法读取已定义对象上未定义的 属性 'name'?

React Cannot read property 'name' of undefined on object that is defined?

我一直收到错误 TypeError: Cannot read property 'name' of undefined 当我尝试在细分对象上引用 .name 时,它​​指的是那里的代码结尾。我认为正在发生的事情是它试图在页面实际加载之前引用它。它一直在工作,直到我开始尝试拨打电话以获取城市细分。如果有人能告诉我在实际尝试访问细分状态之前将细分状态设置为 false 时我做错了什么。任何建议将不胜感激。

import React, { useState, useEffect } from "react";
import axios from "axios";
import { Link, navigate } from "@reach/router";

const SubdivisionDetails = (props) => {
    const [subdivision, setSubdivision] = useState(false);

    const getSubdivision = () => {
        axios
            .get("http://localhost:8000/api/subdivisions/" + props.id)
            .then((res) => {
                console.log(res);
                setSubdivision(res.data);
            })
            .catch((err) => console.log("Error: ", err));
    };
    useEffect(() => {
        getSubdivision();
    }, [props.id]);

    const { removeSubdivisionFromDom } = props;

    return (
        <div className="mt-5 container">
            <div className="row justify-content-center mb-3">
                <h2>
                    {subdivision ? subdivision.name : ""} -
                    {subdivision ? subdivision.city.name : ""}
                </h2>
            </div>

首先,我会将 subdivision 设置为一个空对象而不是 false 作为其初始状态,因为这是数据将 returning 的类型。

其次,我会使用可选链接,它会在对象链中进行之前检查对象数据是否存在,因此如果它不存在就不会 return 错误,只是 return未定义。

这将使您的 return 语句看起来像这样:

 {subdivision?.name} - {subdivision?.city?.name}

注意每个新对象变量前的 ?.

我几乎已将三元运算符更改为逻辑 && 运算符,因为您没有 else 条件。

每当您依赖从对服务器的 API 调用中获取的数据来填充您的视图时,最好防范 API returns null/empty 值。

在这种情况下,您可以使用两个守卫来确保 subDivision(使用驼峰式命名)状态确实存在。

  1. 添加 Loader component/logic 以显示加载视图,直到从服务器获取全部数据。示例:
    // previous code as is
    useEffect(() => {
        getSubdivision();
    }, [props.id]);

    const { removeSubdivisionFromDom } = props;

    if (!subdivisions || subdivisions === {}) { // ----> Guard against null/empty values
      return (
         <p>Loading...</p>
      )
    }

    return (
        <div className="mt-5 container">
            <div className="row justify-content-center mb-3">
                <h2>
                    {subdivision ? subdivision.name : ""} -
                    {subdivision ? subdivision.city.name : ""}
                </h2>
            </div>
   )
}
  1. 在尝试访问嵌套的 objects/keys 时,始终确保您有选择地链接(使用 ? 运算符)。示例:
 return (
        <div className="mt-5 container">
            <div className="row justify-content-center mb-3">
                <h2>
                    {subdivision?.name || ""} -
                    {subdivision?.city?.name || ""}
                </h2>
            </div>
   )

请阅读这些参考资料以更清楚地理解我阐述的要点:

How to handle AJAX requests - Official React Docs

Why use guard clauses?