ページネーションの作成
コンポーネント
映画リストコンポーネント
frontend/src/app/components/movie/MovieList.tsx
'use client';
import { Movie } from '@/types/data';
import React, { useEffect, useState } from 'react';
import MovieCard from './MovieCard';
import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos'; //<- 追加
import ArrowBackIosIcon from '@mui/icons-material/ArrowBackIos'; //<- 追加
type Props = {
phrase: string;
movies: Movie[];
perPage: number;
};
const MovieList = (props: Props) => {
const [movies, setMovies] = useState<Movie[]>(props.movies);
const [currentMovies, setCurrentMovies] = useState<Movie[]>();
const [currentPage, setCurrentPage] = useState(0); // <- 追加
useEffect(() => {
const start = props.perPage * currentPage; // <- 修正
const end = start + props.perPage;
const currentMovies_ = movies.slice(start, end);
setCurrentMovies(currentMovies_);
}, [movies, currentPage]); // <- currentPageを追加
// ↓追加
const handlePageChange = (page: number) => {
page = page < 0 ? Math.max(Math.floor((movies.length - 1) / props.perPage), 0) : page;
page = page >= Math.ceil(movies.length / props.perPage) ? 0 : page;
setCurrentPage(page);
};
// ↑追加
return (
<>
<div className="text-xl font-bold text-gray-800">{props.phrase}</div>
<div className="mx-4 my-4 flex justify-between">
{/* ↓追加 */}
<button
className="cursor-pointer rounded-md border-2 border-gray-200 text-gray-800 hover:bg-gray-100 active:border-gray-300 active:bg-gray-200"
onClick={() => handlePageChange(currentPage - 1)}
>
<ArrowBackIosIcon />
</button>
{/* ↑追加 */}
{currentMovies?.map((movie) => <MovieCard movie={movie} key={movie.id} />)}
{/* ↓追加 */}
<button
className="cursor-pointer rounded-md border-2 border-gray-200 text-gray-800 hover:bg-gray-100 active:border-gray-300 active:bg-gray-200"
onClick={() => handlePageChange(currentPage + 1)}
>
<ArrowForwardIosIcon />
</button>
{/* ↑追加 */}
</div>
</>
);
};
export default MovieList;
ブラウザで下記URLにアクセスすると、映画リストが表示されます。また、左右のボタンを押すことでページが切り替わります。