Skip to content Skip to sidebar Skip to footer

Update Axios Request For Pagination

I have an axios GET request that displays an array of data, but only displays 15 items at a time. The API url uses multiple pages like example.com/?page=1. I want to create some so

Solution 1:

I want to create some sort of pagination where I can select the next page

Create paging component like this:

function PageSelector(props) {
  const pages = [];

  for (let i = 1; i <= props.numberOfPages; i++) {
    pages.push(
      <div key={i} onClick={() => props.handleClick(i)}>{i}</div>
    );
  }

  return <div>{pages}</div>;
}

This component renders page buttons (it requires good styling, but I leave it for clarity).

Every click on the button with page number updates <App /> component state using handleClick function:

export default class App extends React.Component {
  constructor(props) {
    // ...
    this.state = {
      currentPage: 1,
      numberOfPages: 5
    };
  }

  handleClick(value) {
    this.setState({ currentPage: value });
  }
  
  render() {
    return (
      <div className="App">
        <PageSelector handleClick={this.handleClick} />
      </div>
    );
}

  // ...
}

The currentPage value is passed to CommentsView component to request API. The CommentsView component data is updated on every currentPage change.

class CommentsView extends React.Component {
  constructor(props) { /* ... */ }

  componentDidMount() {
    this.getComments(this.props.postId);
  }

  componentDidUpdate() {
    this.getComments(this.props.postId);
  }

  getComments(postId) {
    axios
      .get(`https://jsonplaceholder.typicode.com/posts/${postId}/comments`)
      .then(response => this.setState({ comments: response.data }))
      .catch(error => console.log(error));
  }

  render() { /* ... */ }
}

You need to use both lifecycle methods - componentDidMount and componentDidUpdate. The first runs when a component is rendered for the first time, the second runs on every component update.

This is how you can change the URL based on the page number you select.


Here is full sample code you can use as a reference:

import React from "react";
import axios from "axios";

export default class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      currentPage: 1,
      numberOfPages: 5
    };
    this.handleClick = this.handleClick.bind(this);
  }

  handleClick(value) {
    this.setState({ currentPage: value });
  }

  render() {
    return (
      <div className="App">
        <CommentsView postId={this.state.currentPage} />
        <PageSelector
          currentPage={this.state.currentPage}
          numberOfPages={this.state.numberOfPages}
          handleClick={this.handleClick}
        />
      </div>
    );
  }
}

function PageSelector(props) {
  const itemStyle = {
    display: "flex",
    justifyContent: "center",
    alignItems: "center",
    width: "30px",
    height: "30px",
    margin: "0 5px",
    border: "1px solid"
  };

  const pages = [];

  for (let i = 1; i <= props.numberOfPages; i++) {
    pages.push(
      <div key={i} onClick={() => props.handleClick(i)} style={itemStyle}>
        {i}
      </div>
    );
  }

  return <div style={{ display: "flex" }}>{pages}</div>;
}

class CommentsView extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      comments: []
    };
  }

  componentDidMount() {
    this.getComments(this.props.postId);
  }

  componentDidUpdate() {
    this.getComments(this.props.postId);
  }

  getComments(postId) {
    axios
      .get(`https://jsonplaceholder.typicode.com/posts/${postId}/comments`)
      .then(response => this.setState({ comments: response.data }))
      .catch(error => console.log(error));
  }

  render() {
    const comments = this.state.comments.map(comment => (
      <li key={comment.id}>{comment.body}</li>
    ));

    return comments.length > 0 ? <ul>{comments}</ul> : <span>loading</span>;
  }
}

(link to codesandbox.io)


Post a Comment for "Update Axios Request For Pagination"