19.12.08 Detail 재복습

sykim·2019년 12월 8일
0

파일 구조

/Routes/Detail/DetailContainer.js

DetailContainer.js

import React from "react";
import DetailPresenter from "./DetailPresenter";

export default class extends React.Component{
        this.state = {
            result:null,
            error:null,
            loading:true
        };
        render() {
        	console.log(this.props)
        	const {result, error, loading} = this.state;
             return (
              <DetailPresenter 
                  result={result}
                  error={error}
                  loading={loading}
              />);
        }
}
  • state 값으로 result, error, loading 을 갖고 있는 DetailPresenter 컨포넌트에 console.log(this.props)를 찍어보면
    => match, location, history 데이터가 보인다
    image.png

DetailContainer 작성에 앞서 우선적으로 생각할 것

1. 어떤 숫자가 현재 페이지에 있는지 알아야한다

image.png

  • match에 파라미터 값(즉, id)이 보이는데 이 값은 Router.js 에서 :id 값에서 온 것
<Route path="/movie/:id" component={Detail} />
<Route path="/show/:id" component={Detail} />

DetailContainer.js

...
async componentDidMount() {
        const {
            match:{params:{id}}, 
            history:{push},
            location: {pathname}
        } = this.props;
        const parsedId = parseInt(id);
        if(isNaN(parsedId)) {
        	// 홈으로 보내고 현재 함수를 종료시킨다 (return을 사용하는 이유)
            return push("/");
        }
...

-만일 전달 받은 id 값이 dddd 와 같은 string이라면(=isNaN) history 함수 중 push를 이용해서 페이지를 "/" 홈으로 보낸다

2. movie/1111로 가는지 tv/1111로 가는지 알아야한다

(왜냐면 movie, tv 둘 다 같은 컨포넌트를 바라보고 있기 때문에)

  • 기본 개념 -> include 에서 받은 값은 true, false 두 값으로 정해진다
    ex
    image.png

DetailContainer.js

...
export default class extends React.Component{
    // state = {
    //     result:null,
    //     error:null,
    //     loading:true
    // };
    constructor(props){
        super(props);
        // 2.
        const{location:{pathname}} = props;
        this.state = {
            result:null,
            error:null,
            loading:true,
            isMovie: pathname.includes("/movie/")
        };
    }
async componentDidMount() {
        const {
            match:{params:{id}}, 
            history:{push},
            // location: {pathname}
        } = this.props;
        // 1. this.isMovie = pathname.includes("/movie/");
        const {isMovie} = this.state;
        const parsedId = parseInt(id);
        if(isNaN(parsedId)) {
            return push("/");
        }
...
    1. componentDidMount 의 this.isMovie 생성자를 전역으로 바꿔보자
    1. state 값들을 constructor (생성자)안에 넣어서 isMovie 라는 클래스를 만든다
      => componentDidMount 에서 if문에 isMovie (true or false) 로 사용

DetailContainer.js

...
export default class extends React.Component{
    constructor(props){
        super(props);
        const{location:{pathname}} = props;
        this.state = {
            result:null,
            error:null,
            loading:true,
            isMovie: pathname.includes("/movie/")
        };
    }
async componentDidMount() {
        const {
            match:{params:{id}}, 
            history:{push}
        } = this.props;
        const {isMovie} = this.state;
        const parsedId = parseInt(id);
        if(isNaN(parsedId)) {
            return push("/");
        }
        let result = null;
        try {
            if (isMovie) {
                // const request = await movieApi.movieDetail(parsedId);
                // result = request.data;
                ({ data : result } = await movieApi.movieDetail(parsedId))
            } else {
                // const request = await tvApi.movieDetail(parsedId);
                // result = request.data;
                ({ data : result } = await tvApi.movieDetail(parsedId))
            }
            console.log(result)
        } catch {
            this.setState({error:"can't find anything"})
        } finally {
            this.setState({loading:false, result})
        }
...
profile
블로그 이전했습니다

0개의 댓글