[TIL] 220317

Lee SyongΒ·2022λ…„ 3μ›” 17일
0

TIL

λͺ©λ‘ 보기
199/204
post-thumbnail

πŸ“ 였늘 ν•œ 것

  1. react 기초 κ°•μ˜ 볡슡(μ™„λ£Œ)

πŸ“š 배운 것 (볡슡)

1. react-router (v6)

movie app λ§Œλ“€κΈ°

App.js νŒŒμΌμ— ν•œκΊΌλ²ˆμ— μž‘μ„±ν–ˆλ˜ μ½”λ“œλ“€μ„ λ‚˜λˆ΄λ‹€.
src/routes/ μ•ˆμ— Home.js와 Detail.js νŒŒμΌμ„ μž‘μ„±ν–ˆλ‹€.
src/components/ μ•ˆμ— Movie.js νŒŒμΌμ„ μž‘μ„±ν–ˆλ‹€.

1) BrowserRouter, Routes, Route

npm i react-router-dom

// App.js
import { BrowserRouter, Routes, Route } from "react-router-dom"; // 이 μ»΄ν¬λ„ŒνŠΈλ“€μ€ url을 바라보고 μžˆλ‹€
import Home from "./routes/Home";
import Detail from "./routes/Detail";

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} /> {/* μ‚¬μš©μžκ°€ root(/)에 있으면 <Home /> μ»΄ν¬λ„ŒνŠΈλ₯Ό λ Œλ”λ§ */}
        <Route path="/movie" element={<Detail />} /> {/* μ‚¬μš©μžκ°€ /movie둜 μ΄λ™ν•˜λ©΄ <Detail /> μ»΄ν¬λ„ŒνŠΈλ₯Ό λ Œλ”λ§ */}
      </Routes>
    </BrowserRouter>
  );
}

export default App;

νŽ˜μ΄μ§€λ₯Ό μ΄λ™ν•˜κ³ μž ν•  λ•Œ a νƒœκ·Έλ₯Ό μ΄μš©ν•΄λ„ λ˜μ§€λ§Œ μ΄λ ‡κ²Œ 되면 전체가 μƒˆλ‘œκ³ μΉ¨ λœλ‹€.
react-router의 Linkλ₯Ό μ΄μš©ν•˜λ©΄ μƒˆλ‘œκ³ μΉ¨ 없이 νŽ˜μ΄μ§€λ₯Ό 이동할 수 μžˆλ‹€.

// Movie.js
import PropTypes from "prop-types";
import { Link } from "react-router-dom";

function Movie({index, title, rating, genres, summary}) {
  return (
    <div>
      <h2 style={{ display: "inline" }}>{index + 1}. <Link to="/movie">{title}</Link></h2>
      <span> - 평점 {rating}점</span>
      <ul>{genres.map((genre) => <li key={genre}>{genre}</li>)}</ul>
      <p>{summary}</p>
  </div>
  );
}

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

export default Movie;

3) useParams (동적 url λ§Œλ“€κΈ°)

μ½”λ“œ μ±Œλ¦°μ§€

ν˜„μž¬ μ‚¬μš©μžκ°€ Homeμ—μ„œ μ˜ν™” 제λͺ©(http: //localhost:3000/movie)을 λˆ„λ₯΄λ©΄ Detail μ»΄ν¬λ„ŒνŠΈλŠ” κ·Έμ € < h1>Detail</ h1> 을 λ°˜ν™˜ν•˜κ³  μžˆλ‹€.
μ΄λ™ν•œ νŽ˜μ΄μ§€μ—μ„œ ν•΄λ‹Ή μ˜ν™”μ— λŒ€ν•œ 정보λ₯Ό 보여주기 μœ„ν•΄μ„œλŠ”, μ΄λ™ν•œ νŽ˜μ΄μ§€μ—μ„œ fetchλ₯Ό μ΄μš©ν•΄ https:// yts.mx/api/v2/movie_details.json?movie_id=...λ‘œλΆ€ν„° 데이터λ₯Ό 가져와야 ν•œλ‹€.
그런데 url의 λ§ˆμ§€λ§‰μ—λŠ” 각각의 movie.id의 값을 λ„£μ–΄μ€˜μ•Ό ν•œλ‹€.
movie.id의 값은 각 νŽ˜μ΄μ§€μ—μ„œ url νŒŒλΌλ―Έν„°λ₯Ό μ΄μš©ν•΄ λ°›μ•„μ˜¬ 수 μžˆλ‹€.

// App.js
function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/movie/:id" element={<Detail />} /> // πŸ’‘ :id μΆ”κ°€
      </Routes>
    </BrowserRouter>
  );
}

export default App;

Routeκ°€ μ§€μΌœλ³΄κ³  μžˆλŠ” url인 /movieλ₯Ό /movie/:id둜 μˆ˜μ •ν•œλ‹€.
idμ—λŠ” μ–΄λ–€ 값이든 올 수 μžˆλ‹€.
μ‚¬μš©μžκ°€ /movie/:id 둜 μ΄λ™ν•˜λ©΄ Detail μ»΄ν¬λ„ŒνŠΈκ°€ λ Œλ”λ§λœλ‹€.

// Detail.js
import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import Movie from "../components/Movie";

function Detail() {
  const { id } = useParams(); // πŸ’‘ useParams() === { id: ... }
  const [loading, setLoading] = useState(true);
  const [movie, setMovie] = useState({});
  const getMovie = async() => {
    const json = await (await fetch(`https://yts.mx/api/v2/movie_details.json?movie_id=${id}`)).json();
    setMovie(json.data.movie);
    setLoading(false);
  };

  useEffect(() => getMovie(), []);

  return (
    <div>
      {/* πŸ’‘ 첫 μ»΄ν¬λ„ŒνŠΈ λ Œλ”λ§ μ‹œ 아직 비동기 μž‘μ—…μ΄ λλ‚˜μ§€ μ•Šμ•„ movie의 값은 {}이닀.
      이둜 인해 λͺ¨λ“  prop이 undefinedκ°€ λ˜μ–΄ PropTypes에 μ˜ν•΄ μ½˜μ†” 창에 κ²½κ³ κ°€ λœ¬λ‹€. loading λ³€μˆ˜λ₯Ό μ΄μš©ν•˜λŠ” μ΄μœ μ΄λ‹€. */}
      { loading
        ? <strong>λ‘œλ”© μ€‘μž…λ‹ˆλ‹€...</strong>
        : <Movie
          id={movie.id}
          title={movie.title_long}
          rating={movie.rating}
          genres={movie.genres}
          summary={movie.description_full}
        />
      }
    </div>
  );
}

export default Detail;

useParamsλ₯Ό μ΄μš©ν•΄ url νŒŒλΌλ―Έν„° id의 값을 λ°›μ•„μ˜€κ³  λ‚˜λ©΄ λ‚˜λ¨Έμ§€λŠ” Home μ»΄ν¬λ„ŒνŠΈμ™€ λ™μΌν•œ λ‘œμ§μ„ 거쳐 λ Œλ”λ§ 과정이 μ§„ν–‰λœλ‹€.

2. github 배포

이 사이에 css μž‘μ—…λ„ ν–ˆλ‹€.

npm i gh-pages

build ν•œ ν›„ deploy ν•΄μ•Ό ν•œλ‹€.
npm run deploy만 μž…λ ₯해도 μžλ™μœΌλ‘œ buildκ°€ μ§„ν–‰λ˜λ„λ‘ deploy와 λ”λΆˆμ–΄ predeploy scriptλ₯Ό μΆ”κ°€ν•œλ‹€.

"scripts": {
  "start": "react-scripts start",
  "build": "react-scripts build",
  "deploy": "gh-pages -d build",
  "predeploy": "npm run build"
}

πŸ™‹β€β™€οΈ 질문

  1. μ§ˆλ¬Έμ„ μœ„ν•΄ μœ„μ—μ„œ μž‘μ„±ν•œ μ½”λ“œμ˜ 일뢀λ₯Ό κ°„λž΅νžˆ μˆ˜μ •ν–ˆλ‹€.
function Detail() {
  const [loading, setLoading] = useState(true);
  const [movie, setMovie] = useState({});
  const getMovie = async() => {
    const json = await (await fetch("...")).json();
    setMovie(json.data.movie);
    setLoading(false);
    console.log(movie); // 1번 μ½˜μ†”λ‘œκ·Έ
  };

  useEffect(() => getMovie(), []);
  
  console.log(movie); // 2번 μ½˜μ†”λ‘œκ·Έ

  return (
    <div>
      { loading
        ? <strong>λ‘œλ”© μ€‘μž…λ‹ˆλ‹€...</strong>
        : <Movie title={movie.title_long} />
      }
    </div>
  );
}

export default Detail;

μœ„ μ½”λ“œμ˜ μ‹€ν–‰ κ²°κ³Ό

  • λ¨Όμ €, 2번 μ½˜μ†”λ‘œκ·Έ μœ„μΉ˜μ—μ„œ 빈 λ°°μ—΄ [] 이 좜λ ₯λœλ‹€.
  • κ·Έ ν›„, 2번 μ½˜μ†”λ‘œκ·Έ μœ„μΉ˜μ—μ„œ (20)[...] κ°€ 좜λ ₯λœλ‹€.
  • μ΄μ–΄μ„œ, 2번 μ½˜μ†”λ‘œκ·Έ μœ„μΉ˜μ—μ„œ (20)[...]κ°€ 좜λ ₯λœλ‹€.
  • λ§ˆμ§€λ§‰μœΌλ‘œ, 1번 μ½˜μ†”λ‘œκ·Έ μœ„μΉ˜μ—μ„œ 빈 λ°°μ—΄ [] 이 좜λ ₯λœλ‹€.

λ‚΄κ°€ μ΄ν•΄ν•œ λ°”λŠ” λ‹€μŒκ³Ό κ°™λ‹€.

  • λ¨Όμ €, νŽ˜μ΄μ§€κ°€ 처음 열리고 아직 fetchκ°€ μ™„λ£Œλ˜κΈ° 전에 Detail μ»΄ν¬λ„ŒνŠΈ λ Œλ”λ§μ΄ μ§„ν–‰λΌμ„œ 2번 μ½˜μ†”λ‘œκ·Έ μœ„μΉ˜μ—μ„œ 빈 λ°°μ—΄ [] 이 좜λ ₯λœλ‹€.

  • fetchλ₯Ό μ™„λ£Œν•œ ν›„ setMovie(json.data.movie)에 μ˜ν•΄ λ¦¬λ Œλ”λ§μ΄ μΌμ–΄λ‚˜κ³  movie stateκ°€ λ°”λ€Œμ—ˆκΈ° λ•Œλ¬Έμ— 2번 μ½˜μ†”λ‘œκ·Έ μœ„μΉ˜μ—μ„œ 20[...] κ°€ 좜λ ₯λœλ‹€.

  • λ§ˆμ°¬κ°€μ§€λ‘œ setLoading(false)에 μ˜ν•΄ λ¦¬λ Œλ”λ§μ΄ μΌμ–΄λ‚˜κ³  loading stateκ°€ λ°”λ€Œμ—ˆκΈ° λ•Œλ¬Έμ— 2번 μ½˜μ†”λ‘œκ·Έ μœ„μΉ˜μ—μ„œ 20[...] κ°€ 좜λ ₯λœλ‹€.

  • λ§ˆμ§€λ§‰μœΌλ‘œ getMovie ν•¨μˆ˜ λ³Έλ¬Έ μ•ˆμ—μ„œ console.log(movie), 즉 1번 μ½˜μ†”λ‘œκ·Έκ°€ μ‹€ν–‰λœλ‹€.
    πŸ™‹β€β™€οΈ μ—¬κΈ°μ„œ μ•žμ˜ κ³Όμ •κ³Ό μ—°κ³„ν•΄μ„œλ„ μ •ν™•νžˆ μ™œ 빈 λ°°μ—΄ [] 이 좜λ ₯λ˜λŠ” 건지 λͺ¨λ₯΄κ² λ‹€.


✨ 내일 ν•  것

  1. react λ‹€μŒ κ°•μ˜ μ‹œμž‘
profile
λŠ₯λ™μ μœΌλ‘œ μ‚΄μž, ν–‰λ³΅ν•˜κ²ŒπŸ˜

0개의 λŒ“κΈ€