Infinite Scrolling is not working while fetching data

1.2k Views Asked by At

I'm trying to fetch the news in my infinite scrollbar but it is not working properly and every time I run this code my laptop get stuck.

import React, { Component } from "react";
import NewsItem from "./NewsItem";
import Spinner from "./Spinner";
import InfiniteScroll from "react-infinite-scroll-component";
export class News extends Component {
  static defaultProps = {
    country: "us",
    pageSize: 8,
    category: "general",
  };
  // static propTypes={
  //     country:PropTypes.string,
  //     pageSize:PropTypes.number,
  //     category:PropTypes.string
  // }
  capitalizeFirstLetter(str) {
    return str.charAt(0).toUpperCase() + str.slice(1);
  }
  constructor(props) {
    super(props);
    this.state = {
      articles: [],
      loading: true,
      page: 1,
      totalResults: 0,
    };
    document.title = `${this.capitalizeFirstLetter(
      this.props.category
    )} - News Monkey`;
  }
  async updateNews() {
    //this is the function to update news
    try {
      this.setState({
        loading: true,
      });
      let url = `https://newsapi.org/v2/top-headlines?country=${this.props.country}&category=${this.props.category}&apiKey=01b1a8fe6ec74a02b41f4e0050d4d394&page=${this.state.page}&pageSize=${this.props.pageSize}`;
      let data = await fetch(url);
      let parsedData = await data.json();
      this.setState({
        articles: parsedData.articles,
        loading: false,
        totalResults: parsedData.totalResults,
      });
    } catch (e) {
      console.log("something is not working");
    }
  }
  async fetchMoreData() {
    // this.setState({
    //     page: this.state.page + 1,
    // });
    // this.setState.page+=1;
    this.state.page += this.state.page;
    let url = `https://newsapi.org/v2/top-headlines?country=${this.props.country}&category=${this.props.category}&apiKey=01b1a8fe6ec74a02b41f4e0050d4d394&page=${this.state.page}&pageSize=${this.props.pageSize}`;
    let data = await fetch(url);
    let parsedData = await data.json();
    this.setState({
      articles: this.state.articles.concat(parsedData.articles),
      loading: false,
      totalResults: parsedData.totalResults,
    });
  }
  async componentDidMount() {
    this.updateNews();
  }
  handlePrev = async () => {
    this.setState({
      page: this.state.page - 1,
    });
    this.updateNews();
  };
  handleNext = async () => {
    this.setState({
      page: this.state.page + 1,
    });
    this.updateNews();
  };
  render() {
    return (
      <div>
        <h1 className="text-center">
          {" "}
          News Monkey - Top {this.capitalizeFirstLetter(
            this.props.category
          )}{" "}
          Headlines{" "}
        </h1>
        <InfiniteScroll
          dataLength={this.state.articles.length}
          next={this.fetchMoreData}
          // style={{ display: 'flex', flexDirection: 'column-reverse' }} //To put endMessage and loader to the top.
          inverse={true} //
          hasMore={this.state.articles.length !== this.state.totalResults}
          loader={<Spinner />}
          scrollableTarget="scrollableDiv"
        >
          <div className="container my-4">
            <div className="row">
              {this.state.articles.map((element, index) => {
                return (
                  <div className="col-md-4 my-4" key={index}>
                    <NewsItem
                      title={element.title ? element.title.slice(0, 40) : ""}
                      description={
                        element.description
                          ? element.description.slice(0, 40)
                          : ""
                      }
                      urlToImage={element.urlToImage}
                      author={element.author}
                      date={element.publishedAt}
                      url={element.url}
                      source={element.source.name}
                    />
                  </div>
                );
              })}
            </div>
          </div>
        </InfiniteScroll>
      </div>
    );
  }
}
export default News;
1

There are 1 best solutions below

0
On

Adding the function where you have to change url and make page+1 in url and update state after the url. This is an async function so before state is getting updated url is getting created so update like below:

Also You can refer the exact code here link, please like the comment it it helps: https://github.com/anshikaagrawal29/NewsMonkeyApp-React/blob/main/src/Components/News.js

fetchMoreData = async () => { 
 
    let url = `https://newsapi.org/v2/top-headlines?country=${this.props.country}&category=${this.props.category}&apiKey=${this.props.apiKey}&page=${this.state.page+1}&pageSize=${this.props.pageSize}`;
    
    //fetch is used to get the data from api
    this.setState({page : this.state.page + 1})
    let data = await fetch(url);
    let parsedData = await data.json();
    //This is how we set the state variable
    this.setState({
      // concat function : Combines two or more arrays.
      articles: this.state.articles.concat(parsedData.articles),
      totalResults: parsedData.totalResults
    });
  };