React でアプリを作成しました【15】【Movie App 】

## 環境の準備

①ターミナルでreactアプリケーションを作成する。

```
$ npx create-react-app <プロジェクト名>
$ cd <プロジェクト名>
$ npm start
```

② 必要なパッケージをインストールする。

公式サイト：[themoviedb](https://www.themoviedb.org/documentation/api)

```
$ 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】](https://qiita.com/kanfutrooper/items/adfd32c4991d7da15c93)

```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)}>&laquo;</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)}>&raquo;</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](https://www.youtube.com/watch?v=oqJY1L0gnto)