[React] ReactJS로 영화 웹 서비스 만들기 8

전예원·2022년 1월 9일
1

React

목록 보기
8/10

💡 지금까지 공부한 것들을 응용해서 영화 정보를 보여주는 페이지를 만들어보자!

🔴 movie app 초기셋팅(fetch까지)


import { useEffect, useState } from 'react';

function App() {
  const [loading, setLoading] = useState(true);
  useEffect(() => {
    fetch(`https://yts.mx/api/v2/list_movies.json?minimum_rating=9&sort_by=year`)
      .then((response) => response.json())
      .then((json) => console.log(json));
  }, []);
  return <div>{loading ? <h1>Loading...</h1> : null}</div>;
}

export default App;

🟤 then 메서드 사용

function App() {
  const [loading, setLoading] = useState(true);
  const [movies, setMovies] = useState([]);
  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);
      });
  }, []);
  return <div>{loading ? <h1>Loading...</h1> : null}</div>;
}

🟤 async-await 1번째 방법

function App() {
  const [loading, setLoading] = useState(true);
  const [movies, setMovies] = useState([]);
  const getMovies = async () => {
    const response = await fetch(`https://yts.mx/api/v2/list_movies.json?minimum_rating=9&sort_by=year`);
    const json = await response.json();
    setMovies(json.data.movies);
    setLoading(false);
  };
  useEffect(() => {
    getMovies();
  }, []);
  return <div>{loading ? <h1>Loading...</h1> : null}</div>;
}

🟤 async-await 2번째 방법

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> : null}</div>;
}

🟠 data 화면에 출력하기


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();
  }, []);
  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>
              {movie.hasOwnProperty('genres') ? (
                <ul>
                  {movie.genres.map((g) => (
                    <li key={g}>{g}</li>
                  ))}
                </ul>
              ) : null}
            </div>
          ))}
        </div>
      )}
    </div>
  );
}

🟡 Movie 컴포넌트 만들기


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

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();
  }, []);
  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>
  );
}
  • App.jsMovie.js를 import해준다.

🟤 Movie.js

import PropTypes from 'prop-types';

function Movie({ coverImg, title, summary, genres }) {
  return (
    <div>
      <img src={coverImg} alt={title} />
      <h2>{title}</h2>
      <p>{summary}</p>
      <ul>
        {genres && 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;
  • Movie 컴포넌트를 생성한다.

🟢 react route 셋팅


  • react-route-dom 설치해줘야한다.

  • Route라는 폴더를 생성해 주었다.
  • components라는 폴더를 생성해 주었다.

🟤 App.js

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

function App() {
  return null;
}

export default App;

🟤 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=9&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;

🟤 Detail.js

function Detail() {
  return <h1>Detail</h1>;
}

export default Detail;

🔵 react-route-dom으로 경로 설정하기


import { useEffect, useState } from 'react';
import Movie from './components/Movie';
import { BrowserRouter as Router, Switch, Route } from 'react-router-dom';
// BrowerRouter, HashRouter 2가지 종류가 있는데 HashRouter -> http://localhost:3000/#/movie -> #이 붙는 것이다.
// 컴포넌트 import 까먹지 말기!
import Home from './routes/Home';
import Detail from './routes/Detail';

function App() {
  return (
    <Router>
      <Switch>
        <Route path="/movie">
          <Detail />
        </Route>
        <Route path="/">
          <Home />
        </Route>
      </Switch>
    </Router>
  );
}

export default App;

🟤 a태그에 href 속성을 안쓰는 이유?

  • 페이지 전체가 다 로딩되기 때문에
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="/movie">{title}</Link></h2>
      <p>{summary}</p>
      <ul>
        {genres && 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;

🟣 경로에 id 추가해서 id값 받아와서 이동


⚪️ useParams 사용해서 React Router에서 변수 값 넘겨 받기


import { useParams } from 'react-router-dom';


function Detail() {
  const x = useParams()
  console.log(x);
  return <h1>Detail</h1>;
}

export default Detail;

🟤 movie_id의 배열 json으로 받아오기

import { useEffect } from 'react';
import { useParams } from 'react-router-dom';

function Detail() {
  const { id } = useParams();
  const getMovie = async () => {
    const json = await(await fetch(`https://yts.mx/api/v2/movie_details.json?movie_id=${id}`)).json();
    console.log(json);
  };
  useEffect(() => {
    getMovie();
  }, []);
  return <h1>Detail</h1>;
}

export default Detail;

⚫️ 배포하기

  • npm i gh-pages : 다운로드하기

🟤 npm run build

  • npm run build 하면 build 폴더가 생성된다.
  • 지금까지 했던 모든 파일을 깃허브에 올려준다.

🟤 deploy

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

"homepage": "https://yewon97.github.io/react-for-beginners-npx"


  • npm run deploy 라고 코드를 실행 시키면
    저 순서대로 알아서 실행이 된다. 자동으로 배포를 시켜준다.
  • homepage 주소로 들어가게 되면 배포된 사이트가 나온다.

🍎 말줄임표로 요약하기


  • Movie.js 폴더
function Movie({ id, coverImg, title, summary, genres }) {
  return (
    <div>
      <img src={coverImg} alt={title} />
      <h2><Link to={`/movie/${id}`}>{title}</Link></h2>
      <p>{summary.length > 235 ? `${summary.slice(0, 235)}...` : summary}</p>
      <ul>
        {genres && genres.map((g) => (
          <li key={g}>{g}</li>
        ))}
      </ul>
    </div>
  );
}
  • <p>{summary.length > 235 ? ${summary.slice(0, 235)}... : summary}</p>
  • summary의 글자의 수가 235 이상이면
    0~235 글자만 잘라내고 뒤에 말줄임표 ...을 작성해준다.
    만약 235 이하 글은 그대로 보여준다.
profile
앞으로 나아가는 중~

0개의 댓글