보통 요즘은 fetch해서 then하는 것보다 좀 더 보편적으로 async-await을 사용한다.

useEffect(() => {
  fetch(`https://yts.mx/api/v2/list_movies.json?minimum_rating=9&sort_by=year`)
    .then((response) => response.json())
    .then((json) => {
      setMovies(json.data.movies);
      setLoading(false);
    });
}, []);
import React, { useState, useEffect } from "react";

function App() {
  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=9&sort_by=year`
      )
    ).json();
    setMovies(json.data.movies);
    setLoading(false);
  };

  useEffect(() => {
    getMovies();
  }, []); // 최초에만 실행

  console.log(movies);
  return (
    <div>
      {loading ? (
        <h1>Loading..</h1>
      ) : (
        <div>
          {movies.map((movie) => (
            <div key={movie.id}>
              <img src={movie.medium_cover_image} />
              <h2>{movie.title}</h2>
              <p>{movie.summary}</p>
              <ul>
                <li>
                  {movie.genres.map((g) => (
                    <li kye={g}>{g}</li>
                  ))}
                </li>
              </ul>
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

export default App;

movie api를 불러와서 genres 부분을 li 로 보여주는 부분에서
genres가 없는 영화가 포함되는 경우가 발생하여서
uncaught TypeError: Cannot read properties of undefined (reading ‘map’)
에러가 발생하는 경우가 발생하였다.

따라서 hasOwnProperty()함수를 이용하여 미리 genres key가 있는지 확인하고 없으면 null로 처리하는 과정이 필요하다.

  1. fetch, json을 진행 후 로딩을 끝냈기 때문에 반드시 setLoading(false)를 해줘야한다.
  2. then 대신에 async-await을 보편적으로 사용한다.
  3. await을 감싸는 await을 만들 수 있다.
  4. movies.map((movie -> map의 argument는 x, y, z 등등 마음대로 해도 된다.
  5. div key={movie.id} <h2>{movie.title}</h2> 이 컴포넌트들은 movie 배열에 있는 각 movie에서 변형되어 나온 것이다.
  6. key={g} 따로 정해진 key가 없기 때문에 g를 가져와 key로 써준다. 단, g가 고유한 값일 경우에만 가능하다.

  7. key는 React.js에서만, map안에서 component들을 render할 때 사용하는 것이다.
  8. home 라우트(페이지)는 모든 영화를 보여준다.
  9. Movie 라우트는 영화 하나만 보여준다.
  10. 이렇게 라우트 별로 생각해야된다.
  11. home 라우트는 기본적으로 App 컴포넌트 전체를 가지고 있게 만든다.
  12. App에 있는 것을 모두 Home 라우트로 옮겼으니 App.js는 라우터를 랜더한다.

// Movie 컴포넌트가 이 정보들을 부모 컴포넌트로부터 받아온다. // key가 필요하지 않음

=> prop type을 정해주기 위한 설치

npm install prop-types

=> 라우트 하기 위한 설치

npm install react-router-dom

App.js는 router를 render하며 router는 URL을 보고 있는 component이다.

Routes 컴포넌트를 넣어준 것은 한 번에 하나의 Route만 랜더링 하기 위해서이다.

React Router에서는 원한다면 두개의 Route를 한 번에 랜더링 할 수 있다. 우리는 한 번에 Route 하나만 랜더링 되기를 원한다. 그래서 Routes 컴포넌트를 사용하는 것이다.

화면 전체가 재실행되고, 그것을 피하기 위해서 a태그 대신 Link 컴포넌트를 사용한다. Link는 브라우저 새로고침 없이도 유저를 다른 페이지로 이동시켜주는 컴포넌트이다.

동적 다이나믹 라우트를 위해서는 :을 붙여주는 것이 중요하다. ex) /movie/:id

await은 async 함수 내부에 있지 않으면 사용할 수 없다.

Publishing

npm i gh-pages

gh-pages란 결과물을 github pages에 업로드 할 수 있게 해주는 패키지이다.

npm run build

브라우저가 이해할 수 있도록 코드가 압축된다.

package.json 파일에 homepage 코드를 추가한다.

"homepage": "https://uiop5809.github.io/Movie-Website"

scripts에 deploy 코드를 추가한다.
deploy가 하는 일은 우리가 방금 설치한 gh-pages를 실행시키고 “build”라는 디렉토리를 가져와서 homepage에 적어놓은 웹사이트에 업로드 하도록 도와준다.
먼저 build를 하고 난 다음에 deploy를 해야 한다는 걸 기억하고 싶지 않기 때문에 predeploy를 추가한다.
deploy를 실행시키면 predeploy가 자동으로 먼저 실행이 되고 predeploy는 npm run build를 실행시킨다.

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

deploy를 실행하면 node.js가 predeploy를 먼저 실행시킨다.

npm run deploy

댓글남기기