이전 포스팅에 이어서 react router 입니다.


이번이 react router의 마무리 포스팅입니다.


중첩라우팅


이번에는 /post 라는 주소로 접속시 postList를 보여주는 것을 중첩 라우팅으로 구현하여 보겠습니다.


postList 라는 컴포넌트를 만들고, 이 컴포넌트 안에서


/post 라는 주소로 접속시에는 postList 라고 띄워주고, parameter를 넣은 주소 즉 /post/:postId 로 접속시에는 postId를 보여주는것을 만들어 보겠습니다.


우선 containers 폴더에 PostList.tsx 파일을 생성해주세요.


그리고 App.tsx 파일에서 /post 접속시 렌더링되는 component를 변경하겠습니다.


<Route path="/post" component={PostList} />


* src/containers/index.tsx 에 PostList 추가와 App.tsx 에 import 시키는것 잊지 마세요.

* Post.tsx 파일을 components 폴더를 생성하여 빼는 것도 생각해봤는데, 이번에는 그냥 하도록 하겠습니다.


src/containers/PostList.tsx

import * as React from 'react';
import { Route, RouteComponentProps } from 'react-router-dom';
import { Post } from '.';

const PostList = (props: RouteComponentProps<{}>) => {

return (
<div>
<Route exact={true} path={props.match.url} render={() => <h3>포스트 목록</h3>}/>
<Route path={`${props.match.url}/:postId`} component={Post}/>
</div>
);
};

export default PostList;


우선 함수형 컴포넌트로 PostList를 만들겠습니다.


그리고 현재 접속된 주소를 알기위해서 RouteComponentProps를 받고,

라우트를 걸어주겠습니다.

들어온 주소가 정확하게 일치하다면 ( exact = {true} )  포스트 목록이라는 h3 태그를 렌더합니다.

하지만 만약 주소에 parameter가 있다면 Post 컴포넌트를 렌더링 한다는 코드입니다.


* 현재 접속 주소를 아는 방법은 match.url 말고 다른 방법들도 많이 있습니다.

한번 해보시는것을 추천드립니다.

이전 포스팅을 참고하면 알수있을것이라 생각됩니다.


실행시켜보겠습니다.



버튼도 누르면 제대로 동작함을 확인 가능합니다.



Switch


지금까지 Route를 사용하면서, 속성값으로 exact를 사용해보셨습니다.

이것을 쓰지 않을경우, 주소값 일부만 포함되더라도 렌더링 되는것을 막기위해 쓰던 속성이었는데요, Switch 모듈을 사용하면 이것을 쓰지 않고도 사용이 가능합니다.

( 다만 루트 주소의 경우에는 exact를 쓰는것이 좋습니다 )

사용법이나 효과는 다른 언어들에서 사용되는 Switch와 매우 비슷합니다.


Switch는 Route중 매치되는 첫번째 것만 렌더하게 되는데요,


한번 사용해보겠습니다.


App.tsx에서 Switch를 import 해주시고, Route 부분을 Switch 로 감싸주세요.


import { BrowserRouter as Router, Route, Link, Switch } from 'react-router-dom';


<Switch>
<Route exact={true} path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/post" component={PostList} />
</Switch>


실행해도 다른점이 나오지 않을것입니다.


그렇다면 이번에는 Route를 하나 추가하여 해보겠습니다.


<Route exact={true} path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/post" component={PostList} />
<Route path="/:params" render={() => <h1>params</h1>} />


이렇게 추가하고, Switch 를 삭제한다음 실행해보도록 하겠습니다.


그리고 about 이나 post로 접속을 해보면




이처럼 params 가 계속 뜨는것을 볼수있습니다.


이것을 막기 위해서 exact를 다 쓰기보다는 Switch로 해결해보도록 하겠습니다.


다시 Route들을 Switch 로 감싸주세요.


<Switch>
<Route exact={true} path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/post" component={PostList} />
<Route path="/:params" render={() => <h1>params</h1>} />
</Switch>


그리고 실행하면, 원하던대로 렌더링 되는것을 확인할수 있습니다.


하지만 만약 /:params가 위에 있다면 어떻게 될까요?


<Switch>
<Route exact={true} path="/" component={Home} />
<Route path="/:params" render={() => <h1>params</h1>} />
<Route path="/about" component={About} />
<Route path="/post" component={PostList} />
</Switch>


이렇게 about과 post보다 먼저 쓰여지게 되는경우 어떻게 작동하는지 확인해 보도록 하겠습니다.



about, post 모두 params만 렌더링 하게 됩니다.


왜냐하면 가장 먼저 매칭되는것이 :params 이니까요.

( 이러한 이유로 루트의 경우에는 exact를 쓰는것이 편리합니다. )


따라서 Switch를 쓰실때에는 Route 순서에 유의하여 작성하셔야 합니다.


이번에는 지정되지 않은 path로의 접근시 404 페이지를 보여주는 예제를 만들어 보겠습니다.


간단하게 Switch 맨 아래 path를 지정하지 않은 Route를 만들어 주세요.


src/containers/NotFound.tsx

import * as React from 'react';

const NotFound = () => {
return (
<h1>404 Not Found</h1>
);
};

export default NotFound;


src/conatiners/App.tsx

<Switch>
<Route exact={true} path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/post" component={PostList} />
<Route component={NotFound} />
</Switch>


실행한뒤 이상한 주소로 접속해주세요.



저는 localhost:3000/jaro 로 접속했습니다.


제대로 404 Not Found 가 렌더링 되는것을 확인할수 있습니다.


Switch

- <Route> 를 감싸서 사용

- Javascript의 Switch와 비슷

- <Route> 중 매치되는 첫번째만 렌더

- 매치되는 path가 없을때는 아무것도 렌더하지 않음 혹은 path를 지정하지 않은 것을 렌더

- 순서에 유의


Redirect


이번에는 Redirect에 대해 살펴보겠습니다.

Redirect의 경우에는 어떠한 주소로 접속시 그것을 다른 주소로 보내주는것입니다.

다만 여기서의 redirect는 push가 아닌 replace방식이라 history에 남지 않습니다.

location 객체를 통해서도 redirect가 가능합니다.


예제를 통해 살펴보겠습니다.


Admin 이라는 컴포넌트를 생성하겠습니다.


src/containers/Admin.tsx

import * as React from 'react';
import { Redirect } from 'react-router-dom';

const Admin = () => {
const auth = true;
return auth ?
<h1>Admin페이지</h1> :
<Redirect to="/" />;
};

export default Admin;


여기서는 Redirect를 사용하기 위해 import 시켜주었습니다.


또한 인증에 따라 보여주는 페이지가 다르므로 auth 를 보고 true면 Admin 페이지라고 렌더링 하고

그렇지 않다면 redirect 시켜주기 위해 Redirect를 사용하였습니다.

( auth는 구현하지 않고 그냥 쓰도록 하겠습니다. )

기본적으로 Redirect는 Link 와 사용법이 거의 같습니다.


그리고 App.tsx 파일에 Route를 추가해주세요. ( 링크도 추가해주세요 )


<Switch>
<Route exact={true} path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/post" component={PostList} />
<Route path="/admin" component={Admin} />
<Route component={NotFound} />
</Switch>


실행 시켜 보겠습니다.



auth를 true로 해놨으므로 Admin 페이지가 렌더링 되는것을 확인할수 있습니다.


이번에는 auth를 false로 바꾸고 실행해보도록 하겠습니다.



아무리 admin 페이지에 접근하려 해도 접근이 되지 않고, 루트로 redirect되는것을 확인할수 있습니다.


이번에는 redirect의 또다른 사용법입니다.


만일 예전에 쓰던 주소를 다른 주소로 변경하였을때 사용법인데요,


만약 이전에 /info 라는 주소가 있었는데 이 주소를 더이상 쓰지 않고 about으로 redirect 하려 한다면, Switch 안에 redirect를 추가해주시면 됩니다.


App.tsx 에도 Redirect를 import 해주고,

import { BrowserRouter as Router, Route, Link, Switch, Redirect } from 'react-router-dom';


<Switch>
<Route exact={true} path="/" component={Home} />
<Route path="/about" component={About} />
<Redirect from="/info" to="/about" />
<Route path="/post" component={PostList} />
<Route path="/admin" component={Admin} />
<Route component={NotFound} />
</Switch>


Redirect를 추가해주세요.


from 은 이전주소, to는 redirect 시킬 주소입니다.


실행한뒤 /info 주소로 접속해보시면, redirect되는것을 확인할수 있습니다.


from은 꼭 Switch와 같이 쓰시기 바랍니다.


왜 그런지 궁금하신분들은 Switch를 빼고 해보시면 바로 이유를 알수있을거라 생각됩니다.


( 주소로 접근시 무조건 redirect 됩니다.. )


NavLink


NavLink 는 조금 특별한 Link입니다.

to 에 지정한 path와 URL이 매칭되는 경우 특별한 스타일 부여 가능합니다.


이전에 만든 Link들을 NavLink로 바꾸어서 사용해보도록 하겠습니다.


<nav>
<ul>
<li>
<NavLink to="/" activeStyle={{ fontWeight: 'bold', color: 'blue' }}>Home</NavLink>
</li>
<li>
<NavLink to="/about" activeStyle={{ fontWeight: 'bold', color: 'blue' }}>About</NavLink>
</li>
<li>
<NavLink to="/post" activeStyle={{ fontWeight: 'bold', color: 'blue' }}>Post</NavLink>
</li>
<li>
<NavLink to="/admin" activeStyle={{ fontWeight: 'bold', color: 'blue' }}>Admin</NavLink>
</li>
</ul>
</nav>


모두 NavLink로 바꾸고 activeStyle를 추가해주었습니다.


이제 path와 URL이 매치되면 글자가 굵어지고 파란색이 되어야 합니다.


실행해 보도록 하겠습니다.



괜찮은거 같은데 뭔가 이상합니다.


Home 글자는 계속 Active 상태인것처럼 나오네요.


루트 NavLink에는 exact={true} 를 추가해주세요.



이제 원하는대로 동작합니다.



여기까지가 기본적인 react router V4 에 대한 내용이었습니다.

강의를 해주신 이현섭님께 감사드립니다.


원래 다음 포스팅은 스터디 순서에 맞게 react 를 server side rendering으로 바꾸는 법을 해야하지만, 좀더 공부를 하고 포스팅을 하기 위해 잠시 넘어가고 redux에 대해 포스팅 하려고 합니다.


좀더 열심히 공부하여 더 좋은 포스팅을 쓰도록 노력하겠습니다.


감사합니다.


이번 포스팅의 소스주소입니다.


https://github.com/JaroInside/tistory-react-typescript-study/tree/12.react-router-part3



참고 슬라이드 - http://slides.com/hyunseob/react-router#/

참고 동영상 - https://www.youtube.com/playlist?list=PLV6pYUAZ-ZoHx0OjUduzaFSZ4_cUqXLm0



'React > React&typeScript' 카테고리의 다른 글

13. redux - part2  (0) 2017.07.24
13. redux - part1  (0) 2017.07.23
12. REACT ROUTER V4 - part2  (0) 2017.07.20
12. React Router V4 - part1  (0) 2017.07.19
11. 서버사이드 렌더링 , 클라이언트 사이드 렌더링  (4) 2017.07.18
블로그 이미지

Jaro

대한민국 , 인천 , 남자 , 기혼 , 개발자 jaro0116@gmail.com , https://github.com/JaroInside https://www.linkedin.com/in/seong-eon-park-16a97b113/

,