環境の準備
①ターミナルでreactアプリケーションを作成する。
$ npx create-react-app <プロジェクト名> --template typescript
% cd <プロジェクト名>
% yarn start
② 必要な環境を整える。
ESLintとPrettierとを基本からまとめてみた【React+TypeScriptのアプリにESLintとPrettierを導入】
$ npm i -D tailwindcss postcss autoprefixer
$ npm i tailwind-scrollbar-hide
$ npx tailwindcss init -p
$ yarn add axios
$ yarn add react-router-dom
$ yarn add react-paginate
③不要なファイルを削除する。
App.test.ts
logo.svg
reportWebVitals.ts
setupTests.ts
コンポーネント・ファイル構成
src
├─ components
├── Movie.tsx
└── Navbar.tsx
├── App.tsx
├── index.css
└── index.tsx
├── .env
├── tailwind.config.ts
src/components/Movie.tsx
import React from 'react';
const IMG_API = 'https://image.tmdb.org/t/p/w1280';
type Props = {
title: string;
poster_path: string;
overview: string;
};
const Movie: React.FC<Props> = ({ title, poster_path, overview }) => {
return (
<div className='.flex flex-wrap .m-3 w-80 relative group overflow-hidden'>
<img
className='max-w-full pt-10'
src={IMG_API + poster_path}
alt={title}
/>
<div className='movie-info'>
<h1 className='text-xl font-bold'>『 {title} 』</h1>
</div>
<div className='absolute bottom-0 left-0 right-0 p-4 text-white transition ease-in-out delay-300 translate-y-full bg-black group-hover:translate-y-0'>
<h2 className='text-xl'>Overview</h2>
<p>{overview}</p>
</div>
</div>
);
};
export default Movie;
src/components/NabBar.tsx
const NavBar: React.FC = () => {
return (
<div className='w-full'>
<div className='text-white text-2xl font-bold md:text-4xl lg:text-5xl ml-4 pt-4'>
Front-end Moivies App
</div>
</div>
);
};
export default NavBar;
src/App.tsx
import { useEffect, useState } from 'react';
import Movie from './components/Movie';
import NavBar from './components/NavBar';
import axios from 'axios';
import loading_spinner from './assets/loading_spinner.gif';
import ReactPaginate from 'react-paginate';
async function getMovies(pageNo: number) {
const res = await axios.get(
`https://api.themoviedb.org/3/trending/movie/day?api_key=${process.env.REACT_APP_API_KEY}&page=${pageNo}`
);
console.log(res.data.results);
return res.data.results;
}
function App() {
const [movies, setMovies] = useState('Loading');
const [pageNo, setPageNo] = useState(1);
useEffect(() => {
getMovies(pageNo)
.then((res) => {
setMovies(res);
})
.catch((err) => {
alert(err);
});
}, [pageNo]);
if (movies === 'Loading' || !movies || movies.length === 0)
return (
<div className='flex items-center justify-center h-screen bg-gray-200'>
<img src={loading_spinner} alt='loading' height='200px' width='200px' />
</div>
);
else
return (
<div className='flex flex-col h-full max-h-screen bg-black'>
<NavBar />
<div className='w-[250] mt-5 pb-10 font-bold pt-8'>
<ReactPaginate
previousLabel={'Previous'}
nextLabel={'Next'}
breakLabel={'...'}
pageCount={1000}
marginPagesDisplayed={3}
pageRangeDisplayed={3}
onPageChange={(e) => setPageNo(e.selected + 1)}
containerClassName={
'text-white justify-center items-center flex gap-x-5 gap-y-1.5'
}
pageClassName={
'inline-flex justify-center items-center h-10 w-10 text-base font-bold bg-white rounded-full hover:border-black hover:font-bold '
}
pageLinkClassName={
'inline-flex justify-center rounded-full align-middle text-black'
}
breakClassName={
'inline-flex justify-center items-center h-10 w-10 text-base font-bold bg-white rounded-full'
}
breakLinkClassName={
'inline-flex justify-center rounded-full align-middle text-black'
}
activeClassName={'bg-green-400'}
/>
</div>
<div className='box-border bg-black text-white font-sans .m-0 grid grid-cols-5 gap-5 items-center'>
{movies.length > 0 &&
Array.isArray(movies) &&
movies.length > 0 &&
movies.map((movie: any) => <Movie key={movie.id} {...movie} />)}
</div>
</div>
);
}
export default App;
src/index.css
@import url('https://fonts.googleapis.com/css2?family=Poppins&display=swap');
@tailwind base;
@tailwind components;
@tailwind utilities;
html {
background-color: black;
}
.gitignore
//省略
.env //追加する
.env
REACT_APP_API_KEY= APIKEYを入力;
tailwind.config.js
module.exports = {
content: ['./src/**/*.{tsx,ts}'],
theme: {
extend: {},
},
plugins: [require('tailwind-scrollbar-hide')],
};
参考サイト
Movies App - React Project
react-paginateを使用してページネーション用コンポーネントを作成する
React js Pagination With API Call Using React-paginate