[ReactJS로 영화 웹 서비스 만들기 실습] Movie API + React Router Dom

IRISH·2024년 5월 2일

ReactJS-Movie-Web-Service

목록 보기
22/23
post-thumbnail

진행사항

  • React Router Dom과 BrowserRouter에 대해 실습한다.
  • Link에 대해 실습한다.

코드

src/routes/Detail.js

function Detail() {
  return <h1>Detail</h1>;
}
export default Detail;
  • / 에서 (즉, Home에서) 특정 영화 제목을 클릭하면 Detail 글자가 나오는 화면을 볼 수 있음

src/components/Movie.js

import PropTypes from "prop-types";
import { Link } from "react-router-dom";

function Movie({ coverImg, title, summary, genres }) {
  return (
    <div>
      <img src={coverImg} alt={title} />
      <h2>
        <Link to="/detail">{title}</Link>
      </h2>
      <p>{summary}</p>
      <ul>
        {genres.map((g) => (
          <li key={g}>{g}</li>
        ))}
      </ul>
    </div>
  );
}

Movie.propTypes = {
  coverImg: PropTypes.string.isRequired,
  title: PropTypes.string.isRequired,
  summary: PropTypes.string.isRequired,
  genres: PropTypes.arrayOf(PropTypes.string).isRequired,
};

export default Movie;
  • Link
    • 이거를 사용하지 않으면 라우팅을 할 때마다 페이지가 새로고침 됨
    • 이 문제를 방지하기 위해 Link 를 react-router-dom을 통해 import 함

  • a 태그를 안 쓰고 link를 쓰는 이유
    • Link 컴포넌트를 사용하고 실제 페이지를 확인해보면 a 태그로 변환되어있는 것을 확인할 수 있음
    • 그런데, 왜 Link 컴포넌트를 사용할까?
      • a 태그는 페이지 이동 시 매번 새로운 페이지를 요청해서 받아와 약간의 변동사항이 있더라도 전체 화면을 매번 다시 렌더링하여 비효율적
      • 반면, Link 컴포넌트는 실제 서버에 요청을 보내지 않고 url만 변경됨
      • 그래서 실제 화면에서 바뀌어야 하는 부분만 새로 렌더링 되기 때문에 효율적
  • a 태그는 사용하면 안될까?
    • 애플리케이션 내부에서 페이지를 전환해야 할 때는 Link 컴포넌트를 사용하고, 외부 사이트로 이동할 때는 a 태그를 사용함
    • 외부 사이트로 이동시에는 항상 전체 페이지를 받아와야 하기 때문

src/routes/Home.js

import { useEffect, useState } from "react";
import Movie from "../components/Movie";

function Home() {
  const [loading, setLoading] = useState(true);
  const [movies, setMovies] = useState([]);
  const getMovies = async () => {
    const json = await (
      await fetch(
        `https://yts.mx/api/v2/list_movies.json?minimum_rating=8.8&sort_by=year`
      )
    ).json();
    setMovies(json.data.movies);
    setLoading(false);
  };
  useEffect(() => {
    getMovies();
  }, []);
  return (
    <div>
      {loading ? (
        <h1>Loading...</h1>
      ) : (
        <div>
          {movies.map((movie) => (
            <Movie
              key={movie.id}
              coverImg={movie.medium_cover_image}
              title={movie.title}
              summary={movie.summary}
              genres={movie.genres}
            />
          ))}
        </div>
      )}
    </div>
  );
}
export default Home;
  • 저번 파트와 동일

src/App.js

import { BrowserRouter as Router, Switch, Route } from "react-router-dom";
import Detail from "./routes/Detail";
import Home from "./routes/Home";
function App() {
  return (
    <Router>
      <Switch>
        <Route path="/test">
          <h1>Test Page</h1>
        </Route>
        <Route path="/bye">
          <h1>bye Page</h1>
        </Route>
        <Route path="/detail">
          <Detail />
        </Route>
        <Route path="/">
          <Home />
        </Route>
      </Switch>
    </Router>
  );
}

export default App;
  • react-router-dom의 라우터는 와 두 가지가 존재
    • BrowserRouter는 HTML5의 history API를 활용하여 UI를 업데이트하고, HashRouter는 URL의 hash를 활용한 라우터임
    • HashRouter는 정적인(static) 페이지에 적합
    • request와 response로 이루어지는 동적인 페이지를 제작할 때에는 BrowserRouter가 보편적으로 쓰입니다.
  • BrowserRouter
    • BrowserRouter는 HTML5의 History API(pushState, replaceState, popstate event)를 사용하여 URL과 UI를 동기해주는 <Router>이다.
    • 이는 페이지를 새로고침하지 않고도 주소를 변경할 수 있도록 해주고, 현재 주소에 관련된 정보를 props로 조회 및 사용이 가능하도록 한다.
    • BrowserRouter는 리액트 라우터 돔을 적용하고 싶은 컴포넌트의 최상위 컴포넌트를 감싸주는 래퍼 컴포넌트이기 때문에, 여기서는 App 컴포넌트를 감싸주면 된다.
    • Route
      • 요청받은 pathname에 해당하는 컴포넌트를 렌더링
    • Switch
      • path의 충돌이 일어나지 않게 Route들을 관리
        • Swtich 내부에 Route들을 넣으면 요청에 의해 매칭되는 Route들이 다수 있을 때 제일 처음 매칭되는 Route만 선별하여 실행함
          • 따라서 url 겹침이나 충돌 오류를 방지할 수 있음
      • path와 매칭되는 Route가 없을 때에는 맨 밑에 default Route의 실행이 보장됩니다.(path 속성을 설정하지 않은 Route)

느낀점

  • 수업에서는 react-router-dom 의 내용과 그 안에서의 BrowserRouter에 대한 상세한 설명이 없었다. 이 때 이와 관련한 공부를 했었어야 했는데, 그렇게 하지를 못했다.
    • 하지만, 이번 기회를 통해서 react-router-dom와 BrowserRouter를 간략하게라도 알 수 있었다.
  • 또한, App.js 에서 각 라우트의 path를 통해 그 path 안에서의 html 코드나 컴포넌트를 통해 html을 보여줄 수 있음을 실습하였다. 이를 통해, 어떤 식으로 URL이 구성되는지 간략하게 알 수 있었다.
    • 이것을 통해서 REST API도 하는 것이 아닐까?

참고

profile
#Software Engineer #IRISH

0개의 댓글