to run: npm install, npm start
download source
Pagination
Under components/common, create pagination.jsx:
1 2 3 4 5 6 7 8 9 |
import React from 'react'; // stateless functional component const Pagination = (props) => { return (<h3>test</h3>); } export default Pagination; |
We put this in movies.jsx’s render function:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
render() { const { length: count} = this.state.movies; if (count === 0) return <p>No Movies in DB</p>; return ( <React.Fragment> <p>Showing {count} movies in the database.</p> <table className="table"> ... </table> <Pagination /> </React.Fragment> ) } |
Run the app, and we should see our Pagination.
Now, in order to implement Pagination, we should be clear on what it does. Pagination is a component that takes in a total items count, and a specified # of items per page. That way we calculate how many paginations there are for that # of pages.
For example, if we have 10 items, and each page displays 4 items, then our pagination should be 1, 2, 3.
If we have 8 items, and each page displays 4 items, then our pagination should be 1, 2.
Hence, our pagination is actually some HTML that displays an array of numbers. In order to do so, we must pass in total items, with page size from the movies component.
We also add a delete button for future implementation.
movies.jsx
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
import React, { Component } from 'react'; import { getMovies } from '../../src/services/fakeMovieService'; import Pagination from './common/pagination'; class Movies extends Component { state = { movies: getMovies(), pageSize: 10 } // arrow function. 'this' context is parent's this handleDelete = movie => { console.log(`Removing movie ${movie.title}`); // get all movies except our parameter movie // new array const movies = this.state.movies.filter(m => m._id !== movie._id); this.setState({movies}); }; handleLike = movie => { } handlePageChange = page => { console.log(page); } render() { const { length: count} = this.state.movies; if (count === 0) return <p>No Movies in DB</p>; return ( <React.Fragment> <p>Showing {count} movies in the database.</p> <table className="table"> <thead> <tr> <th>Title</th> <th>Genre</th> <th>Stock</th> <th>Rate</th> <th></th> </tr> </thead> <tbody> {this.state.movies.map(movie => { return ( <tr key={movie._id}> <td>{movie.title}</td> <td>{movie.genre.name}</td> <td>{movie.numberInStock}</td> <td>{movie.dailyRentalRate}</td> <td><button onClick={() => this.handleDelete(movie)} className="btn btn-danger btn-sm">delete</button></td> </tr> ); })} </tbody> </table> <Pagination itemsCount={count} pageSize={this.state.pageSize} onPageChange={this.onPageChange} /> </React.Fragment>) } } export default Movies; |
Notice in the Pagination component, we pass in props total movie count, and specified pageSize. Finally, a callback for pageChange.
Our Pagination will take the total count and page size via props, then calculate how many pages should be in our pagination.
Now, we implement Pagination. In order to easily create a function where it puts start…end into an array for you, we install lodash into our app. In your terminal, npm i lodash@4.7.10
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
import React from 'react'; import _ from 'lodash'; // optmized underscore // stateless functional component const Pagination = (props) => { const { itemsCount, pageSize } = props; const pagesCount = itemsCount / pageSize; if (Math.ceil(pagesCount) === 1) { return null; } // Creates an array of numbers (positive and/or negative) // progressing from start up to but not including end. // If start is less than stop a zero-length range is created // unless a negative step is specified. const pagesArr = _.range(1, pagesCount+1); return <nav> <ul className="pagination"> {pagesArr.map(page=> ( <li key={page} className="page-item"> <a className="page-link">{page}</a> </li> ))} </ul> </nav> } export default Pagination; |
Now the pagination should look like this: