微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

React无法读取已定义对象上未定义的属性“名称”?

如何解决React无法读取已定义对象上未定义的属性“名称”?

我不断收到错误 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>

解决方法

每当您依赖从对服务器的 API 调用获取的数据来填充您的视图时,防止出现您的 API 返回 null/空值的情况是一个很好的做法。

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

  1. 添加 Loader 组件/逻辑以显示加载视图,直到从服务器获取整个数据。示例:
    // 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. 在尝试访问嵌套对象/键时,始终确保您可以选择链接(使用 ? 运算符)。示例:
 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?

,

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

其次,我会使用可选链,它在对象链中继续执行之前检查对象数据是否存在,因此如果不存在则不会返回错误,而只是返回未定义。

这会让你的 return 语句看起来像这样:

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

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

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。