"TypeError: Cannot read property 'name' of undefined" when using useState and useEffect

"TypeError: Cannot read property 'name' of undefined" when using useState and useEffect

我刚开始使用 useState 和 useEffect,我正在尝试从 randomuser api 获取用户并显示它们。我正在按照文档进行操作,我可以看到我的用户数组已登录到控制台。

我可以更改什么,所以它不会告诉我“无法读取未定义的 属性 'name'”。

非常感谢您的帮助。

import axios from "axios";
import { Layout, Loading } from "../components";
// import config from '../config.json';

const Overview = () => {
  const [loading, setLoading] = useState(true);
  const [searchQuery, setSearchQuery] = useState("");
  const [devices, setDevices] = useState([]);

  useEffect(() => {
    async function callApi() {
      const response = await axios.get("https://randomuser.me/api/?results=10");
      const devices = response?.data?.results;
      setDevices(devices);
      // const response = await axios.get(`${config.serverAPI}/devices`);
      // const devices = response?.data?.status === 'success' && response?.data?.devices;
      console.log("Devices", devices);

      await localStorage.setItem("devices", JSON.stringify(devices));
      setLoading(false);
    }
    callApi();
  }, []); // eslint-disable-line react-hooks/exhaustive-deps

  return (
    <Layout>
      <div className="overview-page-wrapper">
        {loading && <Loading />}
        <h2>Title</h2>
        <div>{devices[0].name.first}</div>
      </div>
    </Layout>
  );
};

export default Overview;
import ReactGA from "react-ga";
import { withRouter } from "react-router";
import Disclaimer from "./Disclaimer";
import Header from "./Header";
import Sidebar from "./Sidebar";

const Layout = ({ children, match }) => {
  ReactGA.pageview(match.url);
  console.log(111, match.url);

  return (
    <div className="page-wrapper">
      <Sidebar />
      <div className="main-section">
        <Header />
        <div className="content"> {children} </div>{" "}
      </div>{" "}
      <Disclaimer />
    </div>
  );
};

export default withRouter(Layout);

问题出在你的

return (
    <Layout>
      <div className="overview-page-wrapper">
        {loading && <Loading />}
        <h2>Title</h2>
        <div>{devices[0].name.first}</div>
      </div>
    </Layout>
  );

因为首先调用了 render 方法,然后你的 useEffect hook & 直到那个时候 devices 是一个空数组。

devices[0]undefined

当你做 devices[0].name 时,你实际上是在做 undefined.name

要克服这个问题,你应该做类似的事情

return (
    <Layout>
      <div className="overview-page-wrapper">
        {loading && <Loading />}
        <h2>Title</h2>
        {devices.length > 0 && (<div>{devices[0].name.first}</div>)}
      </div>
    </Layout>
  );

您正在准备加载状态,但它并未覆盖整个渲染,因此当您访问 属性 时它还不存在。

要更正它,您可以试试这个:

<div className="overview-page-wrapper">
  {loading ? 
    <div>loading...</div> 
  : 
    <>
      <h2>Title</h2>
      <div>{devices[0].name.first}</div>
    </>
  }
</div>