0

I am building a news app using React JS. I am using News API to collect the data. I added the next and previous buttons to show the next news by updating the URL using setState. But the problem is the URL is not updating. There is part of URL where &page=1 is and I want to change it to &page=2 and when I check it sends &page=NaN, I don't know why this is happening. Here is the code:-

    import React, { Component } from "react";
import NewsItems from "./NewsItems";
import PreviousIcon from "@material-ui/icons/ArrowBack";
import NextIcon from "@material-ui/icons/ArrowForward";

export default class News extends Component {
  constructor() {
    super();

    this.state = {
      articles: [],
      loading: false,
    };
  }

  async componentDidMount() {
    let url =
      "https://newsapi.org/v2/top-headlines?country=in&apiKey=myapikey&page=1&pageSize=20";

    let data = await fetch(url);

    let parsedData = await data.json();
    this.setState({ articles: parsedData.articles });
  }

  handlePrev = async () => {
    console.log("previous");

    let url = `https://newsapi.org/v2/top-headlines?country=in&apiKey=myapikey&page=${
      this.state.page - 1
    }&pageSize=20`;

    let data = await fetch(url);

    let parsedData = await data.json();

    this.setState({
      page: this.state.page - 1,
      articles: parsedData.articles,
    });
  };

  handleNext = async () => {
    console.log("Next");

    let url = `https://newsapi.org/v2/top-headlines?country=in&apiKey=myapikey&page=${
      this.state.page + 1
    }&pageSize=20`;

    let data = await fetch(url);

    let parsedData = await data.json();

    this.setState({
      page: this.state.page + 1,
      articles: parsedData.articles,
    });
  };

  render() {
    return (
      <div className="news">
        <h1 className="head">SpiceHunt - Top headings</h1>
        <div className="news-items">
          {this.state.articles.map((element) => {
            return (
              <NewsItems
                key={element.url}
                title={element.title}
                description={element.description}
                img={element.urlToImage}
                tag={element.author}
                newsUrl={element.url}
              />
            );
          })}
        </div>
        <div className="pg-btn">
          <button
            className="page-btn"
            disabled={this.state.page <= 1}
            type="button"
            onClick={this.handlePrev}
          >
            <PreviousIcon /> Previous
          </button>
          <button className="page-btn" type="button" onClick={this.handleNext}>
            Next <NextIcon />
          </button>
        </div>
      </div>
    );
  }
}


 

I am a beginner in React JS and this is my first ever question in Stackoverflow. I have very high hope that I will get the solution.

2 Answers2

1

Please add the page in state at initial time.

Older code:

this.state = {
      articles: [],
      loading: false,
    };

Updated code:

this.state = {
      articles: [],
      loading: false,
      page: 1
    };
0

You must use componentDidUpdate() for interact with state did changed. so in this case i use component did update when the state.page did not same with prevState.page so if that condition is true then we tell the react component to update acording to the function inside componentDidUpdate(). I just create some code in below:

don't forget use spread operator or ... to keep previous state in our component. so when we update the state or setState its did'nt erase our previous state.

You can see adjusted code below:

import React, { Component } from "react";
import NewsItems from "./NewsItems";
import PreviousIcon from "@material-ui/icons/ArrowBack";
import NextIcon from "@material-ui/icons/ArrowForward";

export default class News extends Component {
  constructor() {
    super();

    this.state = {
      articles: [],
      loading: false,
      page: 1
    };
  }

  async componentDidMount() {
    let url =
      "https://newsapi.org/v2/top-headlines?country=in&apiKey=myapikey&page=1&pageSize=20";

    let data = await fetch(url);

    let parsedData = await data.json();
    this.setState({ ...this.state, articles: parsedData.articles });
  }

  async componentDidUpdate(_, prevState) {
   if (this.state.page !== prevState.page) {
        let url = `https://newsapi.org/v2/top-headlines? 
        country=in&apiKey=myapikey&page=${
        this.state.page
        }&pageSize=20`;

       let data = await fetch(url);

       let parsedData = await data.json();
       this.setState({
        ...this.state,
        articles: parsedData.articles,
       });
    }
  }

  handlePrev = async () => {
    console.log("previous");

    this.setState({
      ...this.state,
      page: this.state.page - 1,
    });
  };

  handleNext = async () => {
    console.log("Next");

    this.setState({
      ...this.state,
      page: this.state.page + 1,
    });
  };

  render() {
    return (
      <div className="news">
        <h1 className="head">SpiceHunt - Top headings</h1>
        <div className="news-items">
          {this.state.articles.map((element) => {
            return (
              <NewsItems
                key={element.url}
                title={element.title}
                description={element.description}
                img={element.urlToImage}
                tag={element.author}
                newsUrl={element.url}
              />
            );
          })}
        </div>
        <div className="pg-btn">
          <button
            className="page-btn"
            disabled={this.state.page <= 1}
            type="button"
            onClick={this.handlePrev}
          >
            <PreviousIcon /> Previous
          </button>
          <button className="page-btn" type="button" onClick={this.handleNext}>
            Next <NextIcon />
          </button>
        </div>
      </div>
    );
  }
}
Erwin Ramadhan
  • 382
  • 2
  • 10