기록하는 개발자

[React] Movie Rating Web Service-2.0. Detail page, About page 만들기 본문

Web/React

[React] Movie Rating Web Service-2.0. Detail page, About page 만들기

밍맹030 2021. 9. 25. 17:31
728x90

< 구현할 기능 >

 

1. home 화면 : home, about 버튼을 통해 home과 about 페이지로 이동할 수 있다.

2. detail page : home 화면에서 card를 클릭하면 상세 페이지를 보여준다.

3. about 화면

 

파일이 너무 많아 css코드는 생각하겠다.

< App.js >

import React from "react";
import {HashRouter, Route} from "react-router-dom";
import Home from "./routes/Home";
import About from "./routes/About";
import Detail from "./components/Detail";
import Navigation from "./components/Navigation";
//함수형 component
//Route 의 path는 변수처럼 실제 About과 이름이 달라도 된다.
//-> import {About as Potato} from "./routes/About";

function App(){
    return (
    <HashRouter>
        <Navigation/>
        <Route path="/" exact={true} component={Home}/>
        <Route path="/about" component={About}/>
        <Route path="/movie/:id" component={Detail}/>
    </HashRouter>
    );
}

export default App;

< Home.js  > 

import React from "react";
import axios from "axios";
import Movie from "../components/Movie";
import "./Home.css";

class Home extends React.Component {
    state={ 
        isLoading : true,
        movies:[]
    };

    getMovies = async() =>{
        const {
            data: { 
                data: { movies },
            },
        }= await axios.get("https://yts-proxy.now.sh/list_movies.json?sort_by=rating");
        this.setState({movies, isLoading : false});
    }

    componentDidMount(){
        this.getMovies();
    }

    render(){
        const {isLoading, movies} = this.state;
        return (
        <section className="container">
            {isLoading ? (
            <div className="loader">
                <span className="loaderText">Loading...</span>
            </div>
            ) : (
            <div className="movies">
                {movies.map(movie => (
                    <Movie 
                        key = {movie.id}
                        id={movie.id} 
                        year={movie.year} 
                        title={movie.title} 
                        summary={movie.summary} 
                        poster={movie.medium_cover_image}
                        genres={movie.genres}
                    />
                ))}
            </div>
            )}
        </section>
        );
    }
}

export default Home;

< Detail.js  >

import React from "react";
import "./Detail.css";

class Detail extends React.Component{
    componentDidMount(){
        const {location, history} = this.props;
        if(location.state === undefined){
            history.push("/");
        }
    }
    render(){
        const {location} = this.props;
        if(location.state) {
            return (
                <div className="movie-detail">
                <img src={location.state.poster} alt={location.state.title} title={location.state.title}/>
                <div className="detail-movieData">
                    <div className="detail-display">
                        <h3 className="detail-movieTitle">{location.state.title}</h3>
                        <h5 className="detail-movieYear">{location.state.year}</h5>
                    <ul className="detail-movieGenre">
                        {location.state.genres.map((genre, index)=> <li key={index} className="genres_genre">{genre}</li>)}
                    </ul>
                    <p className="detail-movieSummary">{location.state.summary}</p>
                    </div>
                </div>       
            </div>
            );
        }
        else return null;

    }
}
export default Detail;

< About.js  >

import React from "react";
import "./About.css";

function About(props){
    return(
        <div className="aboutPage">
            <span className="content">
                this is about page of movie introduction website
                using ReactJs with movie API.
                <span className="date">2021.09.25</span>
            </span>
        </div>
    );
}

export default About;

< Navigation.js  >

import React from "react";
import {Link} from "react-router-dom";
import "./Navigation.css";

function Navigation(){
    return(
        <div className="nav">
            <Link to="/" className="home">Home</Link>
            <Link to="/about" className="about">About</Link>
        </div>
    );
}
export default Navigation;


react-router-dom
- 네비게이션을 만들어주는 패키지
- router는 url을 가져다가 확인하고 우리가 라우터에게 무엇을 명령하느냐에 따라 해당하는 컴포넌트를 가져온다.
- Route 안에는 두 개의 중요한 prop이 들어감 
     prop1 : rendering할 screen
     prop2 : what url is going to do


설치
> npm install react-router-dom


function App(){
    return (
    <HashRouter>
        <Route path="/home">
            <h1>Home</h1>
        </Route>
        <Route path="/home/introduction">
            <h1>Introduction</h1>
        </Route>
        <Route path="/about">
            <h1>About</h1>
        </Route>
    </HashRouter>
    );
}

→ /about 과 같이 path 이름이 생성된 url의 경우 단독으로 페이지가 보이지만
    "/home/introduction"  로 이동하였을 경우 Home과 Introduction을 모두 rendering 하여 화면에 보여준다.

→ react router 는 기본적으로 url을 가져와 매치되면 render한다.
ex) /home/introduction에는 /home과 /home/introduction이 매치되므로  둘 다 render

위 현상을 방지 하기 위해 exact={true}를 argument로 추가하여 url이 해당 url과 동일할 때만 rendering 해주도록 한다.

<Link to={{
	pathname : `/movie/${id}`,
	state: { year, title, summary, poster, genres }
}}>

About Link를 클릭하면 react router는 /about을 보여주고 state에 해당하는 정보를 route로 보내줄 수 있다.

728x90