본문 바로가기
Front-end/React\RN

리액트 Movie API를 활용한 영화 목록 사이트

by javapp 자바앱 2022. 6. 7.
728x90

 

 

 

 

react-router-dom 을 5버전대로 다운그레이드

npm install axios react-router-dom@5.2.0 bootstrap-bootstrap
Link to 적용을 위해 index.js 에서 <React.StrictMode>를 주석 처리

  //<React.StrictMode>
    <App />
  //</React.StrictMode>

 

 


 

네비게이션

Navigation.js

import {Container, Nav, Navbar} from "react-bootstrap"

import React from 'react';

const Navigation = () => {
    return (
        <Navbar bg="primary" variant="dark">
        <Container>
            <Navbar.Brand href="/index">Home</Navbar.Brand>
            <Nav className="me-auto">
            <Nav.Link href="/list">MovieList</Nav.Link>
            <Nav.Link href="/about">About</Nav.Link>

            </Nav>
        </Container>
        </Navbar>
    );
};

export default Navigation;
            <Navbar.Brand href="/index">Home</Navbar.Brand>
            <Nav.Link href="/list">MovieList</Nav.Link>
            <Nav.Link href="/about">About</Nav.Link>

 href 에 따라 링크 이동

 


 

 

 

Home.js

import { useEffect, useState } from "react";
import { Container, Row, Col, Spinner } from 'react-bootstrap'
import 'bootstrap/dist/css/bootstrap.min.css';
import axios from 'axios'
import Movie from "../components/Movie";

const Home = () => {
  const [movies, setMovies] = useState([]) //영화 리스트
  const [isLoading, setLoading] = useState(true)

  const getMovies = () => { // 비동기로 json 정보를 가져온다.
    axios.get('https://yts-proxy.now.sh/list_movies.json?sort_by=rating')
      .then((res) => {
        console.log(res)
        setMovies(res.data.data.movies)
        setLoading(false)
      })
  }
  //componentDidMount ,componentDidUpdate
  useEffect(() => {
    getMovies()
  }, [])

  return (
    <Container>
      {
        isLoading ? (
          <Spinner animation="border" role="status">
            <span className="visually-hidden">Loading...</span>
          </Spinner>
        ) : (
          <Row>
            {
              movies.map((movie, index) => {
                return (
                  <Col md={4} key={index}>
                    <Movie
                      key={movie.id}
                      year={movie.year}
                      title={movie.title}
                      summary={movie.summary}
                      poster={movie.medium_cover_image}
                      genres={movie.genres}
                    />
                  </Col>
                )
              })
            }

          </Row>
        )
      }

    </Container>
  )
}

export default Home;

위에서 부터 코드를 분석해보면

 

  movies : 영화리스트를 담는 변수 생성합니다.

  const [movies, setMovies] = useState([]) //영화 리스트
  const [isLoading, setLoading] = useState(true)

 

   axios를 통해 json 정보를 가져옵니다.

  const getMovies = () => {
    axios.get('https://yts-proxy.now.sh/list_movies.json?sort_by=rating')
      .then((res) => {
        console.log(res)
        setMovies(res.data.data.movies)
        setLoading(false)
      })
  }

setMovies() 를 통해 영화정보를 담아야되기 때문에 json 데이터의 구조를 파악합니다.

전체데이터(res)에서 키를 찾아가다보면 movies에 영화 정보가 배열 형태로 있는 것을 알 수 있습니다.

res.data.data.movies


useEffect

 

2번째 파라미터가 [] 일  때 첫 렌더링에 한번 실행

  //componentDidMount ,componentDidUpdate
  useEffect(() => {
    getMovies()
  }, [])

 

2번째 파라미터에 특정 값을 넣게 되면, 컴포넌트가 처음 마운트 될 때에도 호출되고,

값이 바뀔 때에도 호출

function User({ user, onRemove, onToggle }) {
  useEffect(() => {
    return () => {

    };
  }, [user]);

 


  return (
    <Container>
      {
        isLoading ? (
          <Spinner animation="border" role="status">
            <span className="visually-hidden">Loading...</span>
          </Spinner>
        ) : (
          <Row>
            {
              movies.map((movie, index) => {
                return (
                  <Col md={4} key={index}>
                    <Movie
                      key={movie.id}
                      year={movie.year}
                      title={movie.title}
                      summary={movie.summary}
                      poster={movie.medium_cover_image}
                      genres={movie.genres}
                    />
                  </Col>
                )
              })
            }

          </Row>
        )
      }

    </Container>
  )

 

map 을 통해 반복적으로 Movie 컴포넌트를 호출

              movies.map((movie, index) => {
 

 

Movie.js

배열 movies 의 내용을 카드형식으로 보여주는 컴포넌트

import {Card, Button} from 'react-bootstrap'
import {Link, NavLink} from 'react-router-dom'

import React from 'react';

const Movie = ({title, year, summary, poster, genres}) => {
    return (
        <Card style={{ width: '18rem' }}>
        <Card.Img variant="top" src={poster} />
        <Card.Body>
            <Card.Title>{title}</Card.Title>
            <Card.Title>{year}</Card.Title>
            <ul style={{ width: '18rem' }}>
            {
                genres.map((genre, index) => {
                return (
                    <li key={index}>{genre}</li>
                )
                })
            }
            </ul>
            <Card.Text>
            {summary.slice(0, 180)}...
            </Card.Text>
            <Link to={{
            pathname: '/detail',
            state: { year, title, summary, poster, genres }
            }}>
            <Button variant="primary">Detail</Button>
            </Link>
            <NavLink to={{
            pathname: '/detail2',
            state: {
                year, title, summary, poster, genres
            }
            }}>
            <Button variant="secondary">Detail2</Button>
            </NavLink>
        </Card.Body>
        </Card >
    );
};

export default Movie;

<Link to>

            <Link to={{
                pathname: '/detail',
                state: { year, title, summary, poster, genres }
            }}>
            <Button variant="primary">Detail</Button>
            </Link>
            
            <NavLink to={{
                pathname: '/detail2',
                state: {
                    year, title, summary, poster, genres
                }
            }}>
            <Button variant="secondary">Detail2</Button>
            </NavLink>

pathname에 url 경로,

state에 같이 넘길 정보를 { } 안에 담아준다.

 

 


Detail.js

state를 통해 받아온 정보는 props 를 통해 보여준다.

props.location.state.title

import { Card, Container } from 'react-bootstrap'
const Detail = (props) => {
  const { location } = props
  return (
    <Container>
      <Card style={{ width: '30rem' }}>
        <Card.Img variant="top" src={location.state.poster} />
        <Card.Body>
          <Card.Title>{props.location.state.title}</Card.Title>
          <Card.Title>{location.state.year}</Card.Title>
          <ul style={{ width: '18rem' }}>
            {
              location.state.genres.map((genre, index) => {
                return (
                  <li key={index}>{genre}</li>
                )
              })
            }
          </ul>
          <Card.Text>
            {location.state.summary}
          </Card.Text>

        </Card.Body>
      </Card >
    </Container>
  )

}

export default Detail;

 

 

src.zip
0.01MB

 

댓글