En este post vamos a aprender a insertar pagination en nuestros proyectos de React. Veremos como funciona y trataremos las posibles modificaciones que se le pueden aplicar. Este ejercicio se realizará en Visual Studio Code 1.43.2 y con Node.js v.12.8.1

Requisitos previos

Antes de comenzar debemos instalar el paquete que vamos a usar para la paginación. Hay varios, pero en este caso se ha decidido utilizar react-paginate en su versión 6.3.2. Para instalarlo simplemente ejecutamos en nuestra consola de comandos npm install react-paginate --save. Para más información acerca del paquete y sus características visitar https://www.npmjs.com/package/react-paginate.

Dependiendo de como carguemos los datos que vamos a paginar usaremos una forma u otra, en este caso es necesario instalar el paquete de axios ya que vamos a realizar una petición a una api. También instalaremos bootstrap para modificar los estilos de la página (npm install –save axios y yarn add react-bootstrap bootstrap).

Componente Paises.js

En primer lugar tenemos un componente Paises.js, con estos imports y con este constructor.

import React, { Component } from "react";
import axios from "axios";
import Global from "./../Global";
import Table from "react-bootstrap/Table";
import ReactPaginate from "react-paginate";

export default class Paises extends Component {
  constructor(props) {
    super(props);
    this.cargarPaises();
    this.state = {
      paises: [], //TODOS PAISES
      offset: 0, //INDICE A PARTIR DEL CUAL CARGAMOS LOS ELEMENTOS A MOSTRAR
      elements: [], //LOS PAISES QUE SE CARGAN EN LA PAGINA ACTUAL
      perPage: 4, //NUMERO DE ELEMENTOS POR PAGINA
      currentPage: 0 //PAGINA ACTUAL, DEFAULT 0
    };
  }

En paises recibiremos todos los países, la variable offset calcula los elementos que ya han sido visualizamos según avanzamos de página. La variable perPage nos indica cuantos elementos se desplegarán por página. Por último en elements cargaremos los países que se van a visualizar en la página actual.

cargarPaises()

  cargarPaises = () => {
    var request = "/paises";
    var url = Global.urlpost + request;
    axios.get(url).then(res => {
      this.setState(
        {
          paises: res.data,
          pageCount: Math.ceil(this.state.paises.length / this.state.perPage) //TOTAL DE ELEMENTOS ENTRE ELEMENTOS POR PAGINA = NUMERO TOTAL DE PAGINAS
        },
        () => this.setElementsForCurrentPage()
      );
    });
  };

Este es el método cargarPaises, simplemente carga mediante un get los elementos que vamos a utilizar en nuestra aplicación. Mencionar que la variable pageCount lo que se esta haciendo es sacar el número total de páginas que habrá en la aplicación. Posteriormente llamamos al método setElementsForCurrentPage para cargar los paises con su pagination al iniciar la aplicación.

setElementsForCurrentPage()

La función setElementsForCurrentPage determina los elementos que se van a cargar en la página actual.

setElementsForCurrentPage() {
    let elements = this.state.paises
      .slice(this.state.offset, this.state.offset + this.state.perPage)
      .map((pais, i) => {
        return (
          <tr key={i}>
            <td>{pais.idPais}</td>
            <td>{pais.iso}</td>
            <td>{pais.nombre}</td>
          </tr>
        );
      });
    this.setState({ elements: elements });
  }

Guarda en elements los países que corresponden mediante el método slice() y posteriormente los recorre para para guardarlos ya con el formato en el que se van a desplegar.

handlePageClick()

handlePageClick es el último método, con el manejaremos a que página se debe dirigir la app y que elementos va a tener que mostrar.

handlePageClick = paises => {
    const selectedPage = paises.selected;
    const offset = selectedPage * this.state.perPage;
    this.setState({ currentPage: selectedPage, offset: offset }, () => {
      this.setElementsForCurrentPage();
    });
  };

  componentDidMount() {
    this.cargarPaises();
  }

Para ello utilizamos la variable offset, en la que guardamos los elementos anteriores a la página que vamos a visualizar. Por ejemplo si estamos en la página 3 (2) y mostramos por página 4 elementos, offset tendrá el valor de 8, es decir empezaremos a mostrar a partir de nuestro octavo elemento. Para finalizar llamamos a setElementsForCurrentPage para que muestre los elementos correspondientes. Añadir que en componentDidMount nos aseguramos de cargar los países, y por tanto la paginación, cuando se ejecute nuestra aplicación.

<ReactPaginate/>

render() {
    let paginationElement;
    if (this.state.pageCount > 1) {
      paginationElement = (
        <ReactPaginate
          previousLabel={"← Anterior"}
          nextLabel={"Siguiente →"}
          breakLabel={<span className="gap">...</span>}
          pageCount={this.state.pageCount}
          onPageChange={this.handlePageClick}
          forcePage={this.state.currentPage}
          containerClassName={"pagination justify-content-center"}
          pageClassName={"page-link"}
          previousClassName={"page-link"}
          previousLinkClassName={"page-item"}
          nextClassName={"page-link"}
          nextLinkClassName={"page-item"}
          disabledClassName={"disabled"}
          activeClassName={"page-item active"}
          activeLinkClassName={"page-link"}
        />
      );
    }

Este es el objeto ReactPaginate, lo guardamos en la variable paginationElement, solo se guardará si el número de páginas totales es mayor de 1, sino simplemente se desplegaran todos los elementos. Destacaremos varias propiedades del elemento ReactPaginate.

  • pageCount almacena el total de páginas.
  • onPageChange llama a la función que asignemos cuando se produzca un cambio de página, en este caso a handlePageClick.

Para más detalles de todas las propiedades visitar la documentación oficial del paquete (https://www.npmjs.com/package/react-paginate), en este caso corresponden a estilos del elemento.

Vista HTML

Para finalizar con nuestro componente Paises.js devolvemos con un return el HTML que vamos a mostrar.

return (
      <div>
        {this.state.paises.length > 0 && (
          <div>
            <Table striped bordered hover variant="dark">
              <tr>
                <th>ID</th>
                <th>ISO</th>
                <th>NOMBRE</th>
              </tr>
              {this.state.elements}
            </Table>
            <div>{paginationElement}</div>
          </div>
        )}
      </div>
    );
  }
}

App.js y vista final

import React from "react";
import "bootstrap/dist/css/bootstrap.min.css";
import "bootstrap/dist/js/bootstrap.bundle.min";
import Paises from "./components/Paises";

function App() {
  return (
    <>
      <Paises></Paises>
    </>
  );
}

export default App;

En App.js simplemente hacemos estos import y dibujamos un objeto Países.

definitivo1
definitivo2

Y este sería el resultado final de nuestra aplicación, mediante el uso del paquete react-paginate hemos conseguido implementar la funcionalidad de paginar nuestro contenido, algo que resulta muy útil a la hora de trabajar con aplicaciones que listen muchos datos.

  • Autor: Felipe Manso Corchado
  • Curso: Microsoft MCSA Web Applications + Microsoft MCSD App Builder + Xamarin
  • Centro: Tajamar
  • Año académico: 2019-2020

Leave a Comment

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Este sitio usa Akismet para reducir el spam. Aprende cómo se procesan los datos de tus comentarios.