开发者问题收集

使用 componentdidMount() 从新闻 API 获取数据,但出现 Uncaught TypeError: Cannot read properties of undefined in reactjs

2023-12-22
71

我正在尝试构建一个网站,其中将有一个标题部分,其中将显示顶部标题,并且我正在使用新闻 API 来获取标题并使用 componentdidmount() 将获取的数据设置为状态

但是当我运行应用程序时,我收到此错误:

Uncaught TypeError: Cannot read properties of undefined (reading 'backgroundImage')
    at NewsHeader.render (NewsHeader.js:30:1)
    at finishClassComponent (react-dom.development.js:19752:1)
    at updateClassComponent (react-dom.development.js:19698:1)
    at beginWork (react-dom.development.js:21611:1)
    at HTMLUnknownElement.callCallback (react-dom.development.js:4164:1)
    at Object.invokeGuardedCallbackDev (react-dom.development.js:4213:1)
    at invokeGuardedCallback (react-dom.development.js:4277:1)
    at beginWork$1 (react-dom.development.js:27451:1)
    at performUnitOfWork (react-dom.development.js:26557:1)
    at workLoopSync (react-dom.development.js:26466:1)

这是我的代码:

import { Component } from 'react';

export default class NewsHeader extends Component {
  constructor() {
    super();
    this.state = {
      articles: [],
      loading: true,
      error: '',
    };
  }
  async componentDidMount() {
    try {
      let url = `https://newsapi.org/v2/top-headlines?country=in&apiKey=myapikey`;
      let data = await fetch(url);
      let parsedData = await data.json();

      if (parsedData.articles && parsedData.articles.length > 0) {
        this.setState({ articles: parsedData.articles, loading: false });
      } else {
        this.setState({ loading: false });
      }
    } catch (error) {
      console.error('Error fetching data:', error);
      this.setState({ loading: false, error: error.message });
    }
  }
  render() {
    let style = {};
    console.log(this.state.articles);
    if (this.state.articles.urlToImage) {
      style = {
        backgroundImage: `url(${this.state.articles.urlToImage})`,
      };
    } else {
      style = {
        backgroundImage: `url(https://images.unsplash.com/photo-1702957954496-8bba5d73a390?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D)`,
      };
    }
    return (
      <>
        <div
          className="container-fluid newshead-height newshead-background-image"
          style={style}
        >
          <div className="conatiner-fluid background-overlay newshead-height ">
            <h2 className="text-center pt-2 text-light">Top Headlines</h2>
            <h5>{this.state.articles.title}</h5>
            <p>{this.state.articles .description}</p>
          </div>
        </div>
      </>
    );
  }
}

编辑:

控制台:

数据正在控制台上打印

如果我尝试以这种方式(this.state.articles[0].urlToImage)从状态访问数据,我会收到错误,因此我将其更改为(this.state.articles.urlToImage)以显示输出

2个回答

如果没有数据,则应保留之前的状态或分配一个空数组。

if (parsedData.articles && parsedData.articles.length > 0) {
        this.setState({ articles: parsedData.articles, loading: false });
      } else {
        this.setState(prevState => {return {...prevState, loading: false }});
      }

或空数组

else {
        this.setState(prevState => {return {...prevState, articles:[],loading: false }});
      }
Okan Karadag
2023-12-22

我已经尝试了所有能想到的方法,但这是唯一对我有用的方法

为我需要的所有数据声明单独的变量,并将文章从状态中放入变量中,检查数据可用性并将数据分配给相应的变量

工作页面

import { Component } from 'react';
    
    export default class NewsHeader extends Component {
      constructor() {
        super();
        this.state = {
          articles: [],
          loading: true,
          error: '',
        };
      }
      async componentDidMount() {
        try {
          let url = `https://newsapi.org/v2/top-headlines?country=in&apiKey=apikey`;
          let data = await fetch(url);
          let parsedData = await data.json();
    
          if (parsedData.articles && parsedData.articles.length > 0) {
            this.setState({ articles: parsedData.articles, loading: false });
          } else {
            this.setState((prevState) => {
              return { ...prevState, loading: false };
            });
          }
        } catch (error) {
          console.error('Error fetching data:', error);
          this.setState({ loading: false, error: error.message });
        }
      }
      render() {
        let style = {};
        let articles = this.state.articles;
        let title = 'something went wrong ';
        let description = 'something went wrong';
        let backgroundImage =
          'https://images.unsplash.com/photo-1702957954496-8bba5d73a390?q=80&w=2070&auto=format&fit=crop&ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D';
        if (articles.length >= 1) {
          if (articles[4].title) {
            title = articles[4].title;
          }
          if (articles[4].urlToImage) {
            backgroundImage = articles[4].urlToImage;
          }
          if (articles[4].description) {
            description = articles[4].description;
          }
        } else {
        }
        style = {
          backgroundImage: `url(${backgroundImage})`,
        };
        return (
          <>
            <div
              className="container-fluid newshead-height newshead-background-image"
              style={style}
            >
              <div className="conatiner-fluid background-overlay newshead-height ">
                <h2 className="text-center pt-2 text-light">Top Headlines</h2>
                <h5 className="text-light">
                  <strong>{title}</strong>
                </h5>
                <p className="text-light">{description}</p>
              </div>
            </div>
          </>
        );
      }
    }

这不是让它工作的最佳方式,但这似乎是在我的情况下起作用的方式

M S Yugandhar
2023-12-23