環境の準備
①ターミナルでreactアプリケーションを作成する。
$ npx create-react-app <プロジェクト名>
$ cd <プロジェクト名>
$ npm start
② 必要なパッケージをインストールする。
公式サイト:themoviedb
$ npm i react-router-dom@next history
$ yarn add axios
③不要なファイルを削除する。
App.test.js
logo.svg
reportWebVitals.js
setupTests.js
コンポーネント・ファイル構成
src
├─ components
├── Home.jsx
├── MovieBox.jsx
├── Navbar.jsx
├── Pager.jsx
└── Watchlist.jsx
├── App.css
├── App.js
├── index.css
└── index.js
Reactを基本からまとめてみた【27】【useEffect】
src/components/Home.jsx
import { useEffect, useState } from 'react';
import axios from 'axios';
import MovieBox from './MovieBox';
import Pager from './Pager';
const Home = () => {
const [list, setList] = useState();
let [page, setPage] = useState(1);
useEffect(() => {
axios
.get(
`https://api.themoviedb.org/3/movie/top_rated?api_key=${process.env.REACT_APP_API_KEY}&language=en-US&page=${page}`
)
.then(({ data }) => setList(data.results))
.catch((err) => console.log(err));
}, [page]);
return (
<div>
<Pager page={page} setPage={setPage} />
<div className='container'>
<div className='grid'>
{list && list.map((movie) => <MovieBox list={movie} />)}
</div>
<Pager page={page} setPage={setPage} />
</div>
</div>
);
};
export default Home;
src/components/MovieBox.jsx
import React from 'react';
const MovieBox = ({ list }) => {
return (
<div className='movie-box'>
<div className='overlay'>
<img
src={`https://image.tmdb.org/t/p/w300/${list && list.poster_path}`}
alt={`${list && list.title} Poster`}
/>
</div>
</div>
);
};
export default MovieBox;
src/components/Navbar.jsx
import React from 'react';
import { Link } from 'react-router-dom';
const Navbar = () => {
return (
<div className='navbar'>
<div className='logo'>Movie App</div>
<div className='menu'>
<ul className='menu'>
<li>
<Link to='/'>Home</Link>
<Link to='/watchlist'>Watchlist</Link>
</li>
</ul>
</div>
</div>
);
};
export default Navbar;
src/components/Pager.jsx
import React from 'react';
const Pager = ({ page, setPage }) => {
return (
<div className='pagination'>
<a onClick={() => setPage(--page)}>«</a>
<a className={`${page === 1 ? 'active' : ''}`} onClick={() => setPage(1)}>
1
</a>
<a className={`${page === 2 ? 'active' : ''}`} onClick={() => setPage(2)}>
2
</a>
<a className={`${page === 3 ? 'active' : ''}`} onClick={() => setPage(3)}>
3
</a>
<a className={`${page === 4 ? 'active' : ''}`} onClick={() => setPage(4)}>
4
</a>
<a className={`${page === 5 ? 'active' : ''}`} onClick={() => setPage(5)}>
5
</a>
<a className={`${page === 6 ? 'active' : ''}`} onClick={() => setPage(6)}>
6
</a>
<a className={`${page === 7 ? 'active' : ''}`} onClick={() => setPage(7)}>
7
</a>
<a className={`${page === 8 ? 'active' : ''}`} onClick={() => setPage(8)}>
8
</a>
<a className={`${page === 9 ? 'active' : ''}`} onClick={() => setPage(9)}>
9
</a>
<a
className={`${page === 10 ? 'active' : ''}`}
onClick={() => setPage(10)}
>
10
</a>
<a
className={`${page === 11 ? 'active' : ''}`}
onClick={() => setPage(11)}
>
11
</a>
<a
className={`${page === 12 ? 'active' : ''}`}
onClick={() => setPage(12)}
>
12
</a>
<a
className={`${page === 13 ? 'active' : ''}`}
onClick={() => setPage(13)}
>
13
</a>
<a
className={`${page === 14 ? 'active' : ''}`}
onClick={() => setPage(14)}
>
14
</a>
<a
className={`${page === 15 ? 'active' : ''}`}
onClick={() => setPage(15)}
>
15
</a>
<a onClick={() => setPage(++page)}>»</a>
</div>
);
};
export default Pager;
src/components/Watchlist.jsx
import React from 'react';
const Watchlist = () => {
return <div>Watchlist</div>;
};
export default Watchlist;
src/App.css
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
.navbar {
display: flex;
align-items: center;
justify-content: space-between;
padding: 1em 1em;
font-size: 1.5em;
color: white;
background-color: #00ae95;
}
.logo {
font-weight: 800;
}
.menu {
list-style: none;
display: flex;
}
.menu a {
color: white;
text-decoration: none;
margin: 0 2em;
}
.container {
width: 96%;
margin: 1rem auto;
}
.grid {
display: grid;
grid-template-columns: repeat(5, 1fr);
grid-gap: 0.5em;
}
/* Pager */
.pagination {
cursor: pointer;
display: inline-block;
margin: 3em 0;
margin-left: 40em;
}
.pagination a {
color: black;
float: left;
padding: 8px 16px;
text-decoration: none;
transition: background-color 0.3s;
}
.pagination a.active {
background-color: #00ae95;
color: white;
}
.pagination a:hover:not(.active) {
background-color: #ddd;
}
src/App.js
import './App.css';
import Home from './components/Home';
import Navbar from './components/Navbar';
import Watchlist from './components/Watchlist';
import { BrowserRouter as Router, Routes, Route } from 'react-router-dom';
function App() {
return (
<Router>
<Navbar />
<Routes>
<Route path='/' element={<Home />} />
<Route path='/Watchlist' element={<Watchlist />} />
</Routes>
</Router>
);
}
export default App;
src.index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
参考サイト
How to make a Movie Trailer App with ReactJs and TheMovieDB API