본문 바로가기
React

[React] Movie App 만들기(2) - Router을 사용해보자!

by Meaning_ 2022. 5. 6.
728x90
반응형

React router을 사용해 화면을 넘기는 기능을 추가해볼 것이다. 

 

컴포넌트를 이용해 코드 정리

App컴포넌트 리턴값에 엘리먼트들이 너무 많아서 컴포넌트를 하나 만들어주려한다. 컴포넌트는 새로운 파일에 만들면 되는데 Movie.js라는 새로운 파일을 만들었다.

App.js에서 리턴할 때

반드시 Movie컴포넌트 넘겨줄때 key값을 넣어줘야한다! key에는 movie.id

 

App.js 상단에 import

 

./components/movie.js

 

movie 컴포넌트는 리턴함으로써 사실상 UI 에 띄어주는 역할을 수행한다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function Movie({medium_cover_image,title,summary,genres}){
 
    return (
        <div>
         <img src={medium_cover_image}></img>
         <h2>{title}</h2>
         <p>{summary}</p>
         Genre
         <ul>
           {
             genres.map((g)=>
              <li key={g}>{g}</li> 
            )
           }
 
         </ul>
         
      </div>
 
    );
}
export default Movie;
cs

movie.js의 경우 props로 받아와야한다.!

 

이제 movie.js 하단에 proptype을 만들어줄거다. 이 propTypes는 부모로부터 전달받은 prop의 데이터 타입을 검사한다. 자식 컴포넌트에서 명시해놓은 데이터타입과 부모로부터 넘겨받은 데이터 타입이 일치하지 않으면 콘솔에 에러가 뜬다.

 

특히 genres의 경우 배열이기 때문에 arrayOf를 써주는게 중요하다.

 

 

이제 이렇게 정리했으면 페이지를 전환해주는 리액트 Router에 대해 학습해볼 것이다.

 

 

 

 

 

 

 

React Router

 

우선 npm install react-router-dom을 해준다. 

페이지를 두개 만들건데 Home 스크린(모든 영화를 보여줌 -> Home.js)이랑 Movie 스크린(영화 하나만 보여줌->Detail.js)을 만들거다.

routes 폴더를 만들어서 거기에 Home.js라는 Home routes를 생성해준다. 그리고 이 Home routes에는 App.js의 모든 코드를 여기에 넣어준다. 

 

이제 App.js는 더이상 영화를 보여주지 않고 router을 렌더링한다.

router는 URL을 보고 있는 component이고, 만약 Home router에 있다면 Home 컴포넌트를 보여줄 것이다. 

url에 따라서 Home을 보여주거나 Detail을 보여주거나 할 것이다. 

 

.routes/Home.js

 

Home 컴포넌트는 모든 영화를 보여주는 컴포넌트이다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
import {useState,useEffect} from "react";
import Movie from "../components/movie";
 
 
function Home(){
    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=8.5&sort_by=year`
        );
 
        const json=await response.json();
        setMovies(json.data.movies);
        setLoading(false);
    };
    
    useEffect(()=>{
        getMovies();
        
    },[]);
 
 
    return (<div>
        {loading?<h1>Loading...</h1>:
        <div>
        {movies.map((movie)=>
        <Movie
        key={movie.id}
        medium_cover_image={movie.medium_cover_image}
        title={movie.title}
        summary={movie.summary}
        genres={movie.genres}
 
        />
        
        
 
        )}
        </div>}
        
    </div>);
 
}
 
export default Home;
cs

Home.js에서 Movie 파일 import할 때 상위 디렉토리를 가져와야 하므로 ../components 즉 점 두개를 써야한다!

 

https://runtoyourdream.tistory.com/35

 

[기본지식] 절대경로와 상대경로

HTML이나 JSP나 어떤 프로그래밍 언어를 하게 되면 절대경로를 사용할때가 있는데요. 절대경로는 대부분 이해 하시지만 상대 경로는 이해 못하시는 경우가 많습니다. 절대경로 부터 알아볼게요.

runtoyourdream.tistory.com

./routes/Detail.js

 

라우터 두개 만들어야 해서 자리차지 용으로 하나 만들어줬다.

 

 

App.js

실질적으로 라우터가 오는 컴포넌트 , 모든 컴포넌트들의 중심 

 

이제 진짜 라우터를 써보자!

라우터에는 두가지 종류가 있는데 Browser Router와 Hash Router가 있다. 이번에는 Browse Router을 써볼 것이다. 

App.js에 라우터를 써줄 것이다. 

Switch의 역할은 Route를 찾는 것이다. Route는 URL을 의미한다. Route를 찾으면 컴포넌트를 렌더링한다.

 

정리: Switch 컴포넌트를 넣어준 이유는 한번에 하나의 Route만 렌더링 하기 위해서 React Router는 한번에 두개의 Route 렌더링 가능하기 때문.

 

주의사항! - Switch냐 Routes냐!

npm i react-router-dom@5.3.0

Switch를 쓰고 싶으면 위 코드인 5버전을 install해야 하고

만약 Routes를 쓰고 싶으면 6버전을 install하면 된다 

 

홈 화면으로 갈 때 사용할 Route

 

<Route path="/"> 

이게 홈화면으로 간다는 의미이다. 유저가 / 경로에 있으면 Home Route를 렌더링 해줄 것이다. 

 

 

https://v5.reactrouter.com/web/guides/quick-start

 

Declarative routing for React apps at any scale | React Router

Version 6 of React Router is here! React Router v6 takes the best features from v3, v5, and its sister project, Reach Router, in our smallest and most powerful package yet.

reactrouter.com

 

npm start 해봤더니 

Typo in static class property declaration react/no-typos 에러가 떴다.

이건 components 폴더에 있던 movie.js 관련 에러였는데 

원래는 import PropTypes 라고 썼는데 이걸 lowercase로 바꿔야 한다. proptypes로!

https://stackoverflow.com/questions/62203534/typo-in-static-class-property-declaration-react-no-typos

 

Typo in static class property declaration react/no-typos

I created a CRUD app using Redux so, I write code and when export the component I added this line: AddContact.PropTypes = { addContact: PropTypes.func.isRequired }; export default connect(null...

stackoverflow.com

 

propTypes를 소문자로 바꿔준 movie.js 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
import propTypes from "prop-types";
 
 
function Movie({medium_cover_image,title,summary,genres}){
 
    return (
        <div>
         <img src={medium_cover_image} alt={title}></img>
         <h2>{title}</h2>
         <p>{summary}</p>
         Genre
         <ul>
           {
             genres.map((g)=>
              <li key={g}>{g}</li> 
            )
           }
 
         </ul>
         
      </div>
 
    );
}
 
Movie.propTypes={
    medium_cover_image:propTypes.string.isRequired,
    title:propTypes.string.isRequired,
    summary:propTypes.string.isRequired,
    genres:propTypes.arrayOf(propTypes.string).isRequired
 
 
}
export default Movie;
cs

 

Detail Routes 추가하기 

 

movie라는 path를 추가하여 movie 에 있을 때 Detail을 호출해주면 

 

movie로 가면 Detail 컴포넌트가 나온다. 

 

Browser Router와 Hash Route의 차이는?

 

Browser Router는 우리가 예상하는 URL대로 생겼다. 

Hash Router는 #을 더붙인다. 

전자는 /movie 라면 후자는 #/movie 이런식으로 URL을 쓴다. 

 

 

하나의 Router에서 다른 Router로 가는 방법?! -Link 

 

예를 들어 Home 스크린에서 Detail 스크린으로 갈 수 있게 해보겠다. 

 

a태그를 넣어서 href를 사용하는 방법도 있겠지만 이러면 페이지 전체가 다시 실행된다.

 

이런 화면 재실행을 막아주는 컴포넌트가 Link 컴포넌트이다.

Link 컴포넌트는 브라우저의 새로고침 없이도 유저를 다른 페이지로 이동시켜주는 컴포넌트이다. 

 

movie 타이틀에 하이퍼링크를 달아줄 건데 

 

우선 movie.js로 와서 Link를 import할 것이다.

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
import propTypes from "prop-types";
import {Link} from "react-router-dom";
 
function Movie({medium_cover_image,title,summary,genres}){
 
    return (
        <div>
         <img src={medium_cover_image} alt={title}></img>
         <h2>
           <Link to="/movie">
            {title}
           </Link>
          </h2>
         <p>{summary}</p>
         Genre
         <ul>
           {
             genres.map((g)=>
              <li key={g}>{g}</li> 
            )
           }
 
         </ul>
         
      </div>
 
    );
}
 
Movie.propTypes={
    medium_cover_image:propTypes.string.isRequired,
    title:propTypes.string.isRequired,
    summary:propTypes.string.isRequired,
    genres:propTypes.arrayOf(propTypes.string).isRequired
 
 
}
export default Movie;
cs

 

Link를 할때는 Link to ="/route에서 설정해준 경로" 로 쓰면 된다.

나는 /movie 경로를 써줬는데 이렇게 하면 아까 routes에서 설정했던대로 Detail로 향하게 된다.

728x90
반응형

댓글