[react] Router 사용하기

eunbi·2020년 5월 5일
3

React

목록 보기
16/22

설치

npm i react-router
  • 뼈대
npm i react-router-dom
  • 웹에서 사용
  • 보통 react-router-dom만 설치해도 react-router가 같이 설치됨
  • react-router는 react-router-dom에서 내부적으로 쓰이고 우리는 react-router-dom만 사용
npm i react-router-native
  • 앱에서 사용

사용

import { BrowserRouter , Route} from 'react-router-dom'
  1. react dom에서 감싸준다
React.DOM.render(<BrowserRouter> <Hot / > </BrowserRouter>, docu~~)
  1. render에서 감싸준다.
return (
<BrowserRouter>
 <div>
    <Link to="경로1">숫자야구</Link> //Link는 router안에 있어야 동작
    <Link to="경로2">게임</Link>
   </div> 
   
   ////위에는 공통으로 화면이 바뀌지 않는 부분
   //// 아래는 화면이 바뀌는 부분
   
   <div>
   	<Route path = "경로1"  component={NumberBaseBall}/ >
    <Route path = "경로2" component={Game}/ >
   </div>
 </BrowserRouter>

)
  • react Router는 눈속임이다.
  • 페이지가 여러개 있는것이 아니라 여러개있는 척 하는것이다.
  • 페이지의 경로가 실제로는 존재하지 않는다. (router가 가상으로 만들어낸 페이지)
  • 때문에 a태그를 쓰면 에러가 나고 Link를 사용한다.

새로고침, 주소창에 직접 주소를 입력하면 서버쪽에 요청하는 것이기때문에 에러가난다.
서버는 이 주소를 모르고 client인 react만 알고 있는 주소다

동적라우터

return (
<BrowserRouter>
 <div>
    <Link to="/game/index">게임</Link>
    <Link to="/game/baseball">숫자야구</Link>
   </div>
   <div>
   	<Route path = "/game/:name"  component={GameMatcher}/ > // 여기서 router가 props를 넣어주는 것
   </div>
 </BrowserRouter>
  • path는 두 단어로 이루어져있어야 한다.

  • props로 연결 안되어있는데 history, match, location을 쓰고 싶을 때 -> withRouter사용

withRouter

라우터로 연결하지 않은 컴포넌트에서 history, match, location을 쓰고 싶을 때 withRouter를 사용한다
주로 로그인 했을 때 로그인이 성공하면 페이지를 이동 할 때 사용한다.
아래처럼 컴포넌트를 withRouter로 감싸주면 된다.

export default withRouter(WithRouterSample);

match값은 컴포넌트가 불러진 곳의 값을 나타내지만 location은 현재 페이지의 값을 나타낸다

WithRouterSample.js

function WithRouterSample({ history, location, match }) {
  return (
    <>
      <textarea
        readOnly
        value={JSON.stringify(location, null, 2)}
      />
      <textarea
        readOnly
        value={JSON.stringify(match, null, 2)}
      />
      <button onClick={() => history.push("/")}>홈으로 이동</button>
    </>
  );
}

export default withRouter(WithRouterSample);

참고로 JSON.stringify(location, null, 2)의 null과 2의 의미는 들여쓰기를 한다는 뜻이다.

profiles.js

function Profiles() {
  return (
    <>
      <ul>
        <li>
          <Link to="/profiles/user">user</Link>
        </li>
        <li>
          <Link to="/profiles/gildong">gildong</Link>
        </li>
      </ul>
      <Route
        path="/profiles"
        exact
        render={() => <div>사용자를 선택해주세요</div>}
      />
      <Route path="/profiles/:username" component={Profile} />
      <WithRouterSample />
    </>
  );
}

export default Profiles;

Link를 클릭해서 서브라우트를 통해 이동한다 하더라도 profiles컴포넌트의 match값을 나타내는 반면 location은 Link를 클릭해서 이동한 profile의 location값을 나타낸다.

useReactRouter

withRouter대신 hook를 사용할 수 있다.

yarn add use-react-router

우선 위와 같이 hook을 설치한 뒤 아래처럼 사용하면 된다.

import useReactRouter from 'use-react-router';

function RouterHookSample() {
  const { history, location, match } = useReactRouter;
  console.log({ history, location, match });
  return null;
}

export default RouterHookSample;

history

  • 앞으로가기, 뒤로가기등 페이지를 이동한 내역을 간직하고 있다.
  • 메서드로 이동할 수 있다.
  • react는 눈속임으로 url을 이동하기 때문에 react에서 제공하는 history를 사용해야 한다.

history 메서드 종류

  • action : 마지막으로 발생한 액션
    (push - 링크를 클릭해서 이동하기, pop - 뒤로가기, 앞으로가기)
  • block : 사용자가 페이지를 이탈하는 것을 방지
  • go : 뒤로가기(-1 -> 한번 뒤로, -2 -> 두번 뒤로), 앞으로가기(1 -> 한번 앞으로, 2 -> 두번 앞으로)
  • goBack : 뒤로가기
  • goForward : 앞으로가기
  • listen : 경로에 변경이 생겼을 때 특정 함수를 호출할 때 사용
  • push : 특정 경로로 이동
  • replace : 기록을 남기지 않고 특정 경로로 이동 (예 : 현재 about 페이지에서 링크를 클릭해서 페이지 이동 후 뒤로가기를 누르면 about 페이지가 나오는 것이 아니라 about 전 페이지로 이동)

history.block

페이지를 이탈할 때 경고창을 띄운다. 주로 작성중인 페이지가 있는데 페이지를 이동하려 할 때 사용한다.

 useEffect(() => {
    const unBlock = history.block("정말 떠나실 건가요?");

    return () => {
      unBlock();
    };
  }, [history]);

return으로 컴포넌트가 unMount될 때 history block을 제거해야지 하지 않으면 다른 페이지에서도 계속 block이 발생한다.

match

  • params.name에 params 이름이 담겨있어서 동적라우터는 이걸로 분기처리한다.

location

  • pathname에 path가 담겨있다. (game/baseball)
  • 그외 search, hash등이 담겨있다.

분기처리 방법

if(this.props.match.params.name === 'baseball') {
	return <Baseball />
}

parameter, query

페이지 주소에 유동적인 값을 전달할 경우 파라미터와 쿼리로 나눠질수 있다.

파라미터: /profiles/velopert (정해진 특정 데이터를 조회할 때)
쿼리: /about?details=true (다양한 옵션을 줘서 조회할 때)

parameter 조회하기

match로 조회
props로 match값을 받아와서 사용 : match.params로 조회

<Route path='/about/:username component={User}'>

username부분이 match의 값이 된다.

query 조회하기

loaction으로 조회
props로 loaction값을 받아와서 사용 : loaction.search로 조회
이 query를 추출하기 위해 qs라이브러리를 사용한다

qs

query 파싱 라이브러리

사용법

yarn add qs

우선 설치 후

const query = qs.parse(location.search, {
	ignoreQueryPrefix: true
})

ignoreQueryPrefix를 true로 설정해야 ?를 제외 후 파싱한다.
false로 설정한다면 아래처럼 ?를 포함해서 파싱한다.
{?data:'1'}

참고로 파싱된 모든 값은 문자열로 저장이 된다.

switch, exact

  • switch 사용법은 Route를 switch로 감싸주면 된다.

  • switch는 위에서부터 읽기 시작하여 해당하는 path를 발견하면 멈춘다. 때문에 아래와 같은 예제에서 /game을 입력해도 /도 해당되기 때문에 NumberBaseBall을 렌더링하는 문제가 발생한다.

<Switch>
    <Route path = "/"  component={NumberBaseBall}/ >
    <Route path = "/game" component={Game}/ >
</Switch>

위와 같이 path의 / 부분이 곂치기 때문에 react는 두개가 모두 해당한다고 판단하여 두 component 모두 렌더링을 한다.
막기위해서는 exact를 사용

<Switch>
    <Route path = "/" exact component={NumberBaseBall}/ > 
    <Route path = "/game" component={Game}/ >
</Switch>    
  • exact는 정확히 일치할 때에만 렌더링한다

switch는 존재하지 않는 경로일때 경고 메세지를 띄우기 위해 사용할 수 있다.

  <Switch>
        <Route path="/" component={Home} exact />
        <Route path="/about" component={About} />
        <Route
          render={({ location }) => (
            <div>
              <h2>이 페이지는 존재하지 않습니다. :</h2>
              <p>{location.pathname}</p>
            </div>
          )}
        />
  </Switch>
  • 참고 : render는 컴포넌트로 연결하지 않고 렌더링할 페이지를 바로 함수로 만들 수 있다.

위와 같이 하단에 Route 컴포넌트에 location이 없으면 에러 메세지를 띄워준다.

NavLink 는 Link 랑 비슷한데, 현재 경로와 Link 에서 사용하는 경로가 일치하는 경우 특정 스타일 혹은 클래스를 적용 할 수 있다.

 <NavLink
            to="/profiles/user"
            activeStyle={{ background: "black", color: "white" }}
            activeClassName="active"
          >
            user
          </NavLink>
  • activeStyle : active 될 때 스타일을 적용
  • activeClassName : active 될 때 classname을 적용
  • isActive : 조건이 true 일 때 activeStyle을 적용
    match와 location을 파라미터로 가져온다.
    (아래 예시)
 <NavLink
            to="/profiles/user"
            activeStyle={{ background: "black", color: "white" }}
            isActive={(match, location) => {
               return match.params.blbal = 'abkd' //참이면 activeStyle 적용
            }}
          >
            user
          </NavLink>

그 외

Prompt

history.block을 컴포넌트 형태로 사용

<Prompt when={formIsHalfFilledOut} message='떠나실건가요?'/>

Redirect

컴포넌트를 특정 페이지로 이동
history.push를 컴포넌트 형태로 사용

<Redirect to="/about" />

Route Config

JSX 형태로 라우트를 선언하는 것이 아닌 Angular 나 Vue 처럼 배열/객체를 사용하여 라우트 정의하기

참고 https://react.vlpt.us/react-router/04-extra.html

profile
프론트엔드 개발자입니다 :)

0개의 댓글