【问题标题】:Can't read properties of undefined React API call无法读取未定义的 React API 调用的属性
【发布时间】:2022-01-10 10:23:27
【问题描述】:

我正在尝试构建一个加载组件,以便我的应用在加载之前不会尝试显示我的 API 数据,从而导致致命错误。阅读了很多关于 componentWillMount 函数的内容,但这似乎已被弃用。尝试使用 setState 无济于事。

import { useEffect, useState } from "react";
import Marquee from "react-fast-marquee";

const News = () => {
  const [data, setData] = useState({});
  const [loading, setLoading] = useState(false);
  useEffect(() => {
    setLoading(true);
    const getNewsFromApi = async () => {
      const response = await fetch(
        "API_KEY_HERE"
      );
      const responseJson = await response.json();
      console.log("json", responseJson);
      setData(responseJson);
    };
    setLoading(false);
    setInterval(getNewsFromApi, 1000)
    
  }, []);

  if (loading) {
    return <h1> Data is loading...</h1>
  }


  return (
    <div >
    
      <Marquee gradientColor="" speed="120">
        <h1>{data?.articles[0].title}  - </h1>
        <h1>{data?.articles[1].title}  - </h1>
        <h1>{data?.articles[2].title}  - </h1>
        <h1>{data?.articles[3].title} - </h1>
        <h1>{data?.articles[4].title} - </h1>
        <h1>{data?.articles[5].title} - </h1>
        <h1>{data?.articles[6].title} - </h1>
        <h1>{data?.articles[7].title} - </h1>
        <h1>{data?.articles[8].title} - </h1>

      
      </Marquee>
    </div>


  )
}

export default News

【问题讨论】:

  • 加载完成前data的值是多少?不是undefinednull。这是{}。那么,data?articles 的值是多少?这是undefined(即不是数组)。那么data?.articles[0] 的值是多少呢?繁荣。
  • data 设置为加载数据后所期望的值。在数据加载之前,它的值为{},在const [data, setData] = useState({});行中设置

标签: javascript reactjs json


【解决方案1】:

useEffect 钩子在渲染之后运行(参见docs)。那么接下来会发生什么:

  1. 您将loading 初始化为false(通过调用useState(false))。
  2. 组件第一次使用loading=false 呈现,因此它跳过加载占位符并尝试立即呈现{} 的文章列表。这意味着data?.articlesundefined

我会做以下改变:

  1. 更改您的状态声明:
const [loading, setLoading] = useState(true);

这将使组件第一次渲染加载占位符。 2. 使用状态作为文章数组而不是从 API 返回的对象也是有意义的(正如@Bru No 建议的那样)。但是你需要改变你的效果——比如:

setData(responseJson.articles);

【讨论】:

    【解决方案2】:

    您在我建议使用此解决方案的 api 响应之前从状态开始读取信息

    import { useEffect, useState } from "react";
    import Marquee from "react-fast-marquee";
    
    const News = () => {
      const [data, setData] = useState([]);
      const [loading, setLoading] = useState(false);
      useEffect(() => {
        setLoading(true);
        (async function getNewsFromApi(){
          const response = await fetch(
            "API_KEY_HERE"
          );
          const responseJson = await response.json();
          console.log("json", responseJson);
          setData(responseJson);
        })();
        setLoading(false);
      }, []);
    
      if (loading) {
        return <h1> Data is loading...</h1>
      }
      return (
        <div >
          <Marquee gradientColor="" speed="120">
            {data.length > 0 && data.articles.map((item)=> <h1>{item.title} </h1>)}
          </Marquee>
        </div>
      )
    }
    
    export default News

    【讨论】:

    • 感谢您的帮助,但是此解决方案在应用启动时仍然会导致相同的错误
    • 你把状态初始化为空数组了吗?
    猜你喜欢
    • 2021-01-23
    • 2018-06-14
    • 2021-10-15
    • 1970-01-01
    • 2017-12-02
    • 2021-06-25
    • 2022-06-18
    • 2019-04-09
    • 2020-10-10
    相关资源
    最近更新 更多