Hi,
I’m currently following the React tutorial from a couple of years ago and I’ve reached the pagination level now. I did literally everything the same as Mosh, like in the pagination.jsx file, paginate.js file and the Movies component, but the movies won’t render, it shows an empty array. Has something become obsolete in the meantime regarding the export of a .js file to a .jsx file or something similar. I will copy the jsx below. and js files and I hope you will help me, so that I can continue with the practice.
movies.jsx:
import React, { Component } from "react";
import Like from "./common/like";
import Pagination from "./common/pagination";
import ListGroup from "./common/listGroup";
import { getMovies } from "../services/fakeMovieService";
import { getGenres } from "../services/fakeGenreService";
import { paginate } from "../utils/paginate";
class Movies extends Component {
state = {
movies: [],
genres: [],
currentPage: 1,
pageSize: 4,
};
componentDidMount() {
this.setState({ movies: getMovies(), genres: getGenres() });
}
handleDelete = (movie) => {
const movies = this.state.movies.filter((m) => m._id !== movie._id);
this.setState({ movies });
};
handleLike = (movie) => {
const movies = [...this.state.movies];
const index = movies.indexOf(movie);
movies[index] = { ...movies[index] };
movies[index].liked = !movies[index].liked;
this.setState({ movies });
};
handlePageChange = (page) => {
this.setState({ currentPage: page });
};
handleGenreSelect = (genre) => {
this.setState({ selectedGenre: genre });
};
render() {
const { length: count } = this.state.movies;
const {
pageSize,
currentPage,
selectedGenre,
movies: allMovies,
} = this.state;
if (count === 0) return <p>There are no movies in the database</p>;
const filtered = selectedGenre
? allMovies.filter((m) => m.genre._id === selectedGenre._id)
: allMovies;
const movies = paginate(filtered, currentPage, pageSize);
return (
<div className="row">
<div className="col-3">
<ListGroup
items={this.state.genres}
selectedItem={this.state.selectedGenre}
onItemSelect={this.handleGenreSelect}
/>
</div>
<div className="col">
<p>Showing {filtered.length} movies in the database</p>
<table className="table">
<thead>
<tr>
<th>Title</th>
<th>Genre</th>
<th>Stock</th>
<th>Rate</th>
<th></th>
<th></th>
</tr>
</thead>
<tbody>
{movies.map((movie) => (
<tr key={movie._id}>
<td>{movie.title}</td>
<td>{movie.genre.name}</td>
<td>{movie.numberInStock}</td>
<td>{movie.dailyRentalRate}</td>
<td>
<Like
liked={movie.liked}
onClick={() => this.handleLike(movie)}
/>
</td>
<td>
<button
onClick={() => this.handleDelete(movie)}
className="btn btn-danger btn-sm"
>
Delete
</button>
</td>
</tr>
))}
</tbody>
</table>
<Pagination //komponenta sa props
itemsCount={filtered.length}
pageSize={pageSize}
currentPage={currentPage}
onPageChange={this.handlePageChange}
/>
</div>
</div>
);
}
}
export default Movies;
pagination.jsx:
import React from "react";
import _ from "lodash";
import PropTypes from "prop-types";
const Pagination = (props) => {
const { itemsCount, pageSize, currentPage, onPageChange } = props;
const pagesCount = Math.ceil(itemsCount / pageSize);
const pages = _.range(1, pagesCount + 1);
if (pagesCount === 1) return null;
return (
<nav>
<ul className="pagination">
{pages.map((page) => (
<li
key={page}
className={page === currentPage ? "page-item active" : "page-item"}
>
<a className="page-link" onClick={() => onPageChange(page)}>
{page}
</a>
</li>
))}
</ul>
</nav>
);
};
Pagination.propTypes = {
itemsCount: PropTypes.number.isRequired,
pageSize: PropTypes.number.isRequired,
onPageChange: PropTypes.func.isRequired,
currentPage: PropTypes.number.isRequired,
};
export default Pagination;
paginate.js:
import _ from "lodash";
export function paginate(items, pageNumber, pageSize) {
const startIndex = (pageNumber - 1) * pageSize;
return _(items).slice(startIndex).take(pageSize).values();
}
React App: