【问题标题】:Passing axios fetched prop from Parent to Child returns "TypeError: Cannot read property 'x' of undefined"将 axios fetched prop 从 Parent 传递给 Child 返回“TypeError: Cannot read property 'x' of undefined”
【发布时间】:2021-07-17 07:21:00
【问题描述】:

我知道已经有人问过这个问题,但提供的各种 answers 似乎对我的情况不起作用。

父组件

import axios from "axios";
import { useEffect, useState } from "react";
import Child from "../../components/fragments/Child";

// Fetches data with no errors
export default function Parent() {
  const [post, setPost] = useState([]);

  useEffect(() => {
    const fetchPost = async () => {
      await axios.get("http://localhost:xxxxx").then((res) => {
        setPost(res.data);
      });
    };
    fetchPost();
  }, []);

  return (
    <>
      <Child post={post} />
    </>
  );
}

子组件

export default function Child({ post }) {
    return (
        <>
        {console.log(post)}
        {/* Sometimes returns an error because axios hasn't finished fetching */}
        </>
    );
  }

Parent 从服务器获取数据没有错误。但是,当我将数据传递给Child 时,它有时会抛出"TypeError: Cannot read property 'post' of undefined"。这会破坏整个应用程序,因为 Child 正在尝试访问 post 道具,该道具在使用 axios 获取数据之前仍处于其初始空数组状态。

ComponentDidMount() 之类的东西不起作用,因为组件可能已安装,但 axios 仍在获取数据。

解决此问题的最佳方法是什么?如何始终让Child 中的post 数据由Parent 传递,并在尝试访问道具时避免"TypeError:..." 屏幕失败?

【问题讨论】:

  • Child 在初始渲染上传递了有效的 post 属性,一个空数组 ([])。您确定要将父级中的 post 状态更新为您期望的状态吗?似乎您在某个时候将post 状态更新为未定义,然后在子级中访问它。如果 post 由于某种原因未定义,您可以有条件地渲染 Child 组件,但这只是掩盖了代码中的真正问题。
  • @DrewReese 感谢您通过建议有条件地渲染子组件来引导我朝着正确的方向前进。我会试一试,看看能不能达到预期的效果。
  • 它解决了我的问题,非常感谢。如果你用一个例子写一个答案,我会接受它。

标签: javascript reactjs axios react-hooks


【解决方案1】:

似乎您在某个时候将post 状态更新为未定义,然后在子级中访问它。如果 post 由于某种原因未定义/falsey,您可以有条件地渲染 Child 组件。

export default function Parent() {
  const [post, setPost] = useState([]);

  useEffect(() => {
    const fetchPost = async () => {
      await axios.get("http://localhost:xxxxx").then((res) => {
        setPost(res.data);
      });
    };
    fetchPost();
  }, []);

  return post ? <Child post={post} /> : null;
}

如果 post 属性未定义/错误,则在 Child 中防御性地呈现 null。

export default function Child({ post }) {
  return post ? (
    <>
      .... child post JSX
    </>
  ) : null;
}

如果post 未定义,则提供初始值。请注意,如果存在 post 属性并且是其他一些虚假值(null、0、false 等),这将错过边缘情况,所以要小心。

export default function Child({ post = [] }) {
  return (
    <>
      .... child post JSX
    </>
  );
}

【讨论】:

    猜你喜欢
    • 2020-02-07
    • 2018-07-16
    • 1970-01-01
    • 2021-06-25
    • 2020-10-25
    • 2017-04-24
    • 2023-03-15
    • 2018-05-26
    • 1970-01-01
    相关资源
    最近更新 更多