본문 바로가기

Frontend/React&RN

[react-router-dom]BrowserRouter, HashRouter

설치

  • npm i react-router react-router-dom

라우터 적용

  • 라우터를 사용하기 위해선 최상위 컴포넌트를 묶고 시작해야 한다
import React from 'react';
import App from './App';
import { BrowserRouter } from 'react-router-dom';
const Root = () => {
    return (
        <BrowserRouter>
            <App />
          </BrowserRouter>
    );
};

export default Root;

라우터1. BrowserRouter

  • Link 컴포넌트 to속성에 이동할 경로 기술
  • Route 컴포넌트 path속성을 Link의 to속성과 매핑 component에 컴포넌트 경로 기술
  • 새로고침 하면 경로 못찾아서 에러남

라우터2. HashRouter

  • 주소에 해쉬(#)이 붙음
  • 새로 고침해도 그대로 나옴 -> #뒤에는 화면에서 읽는 경로이기 때문
  • 검색엔진으로 못읽는 단점때문에 거의 안씀

withRouter

  • Router 컴포넌트 하위에 있지 않은데 route 기능써야할때
  • HOC 방식으로 컴포넌트 감싸준다.
import React, { Component } from 'react';
import { withRouter } from 'react-router-dom'

class GameMatcher extends Component {
  render() {
    console.log(this.props)
    return (
      <div>
        게임매치
      </div>
    );
  }
}

export default withRouter(GameMatcher);

Route 컴포넌트가 props로 배려주는 객체

history

  • 브라우저의 history와 유사한 객체
  • go(), goback()등 메서드로 컴포넌트 히스토리 조작 가능
  • history.go(숫자) : 양수면 앞으로 음수면 뒤로 이동
  • history.push(경로) : 매개변수에 적힌 경로로 이동

location

  • 현재 URL 위치와 관련된 정보를 가지고 있음
  • 현재 경로가 있는 pathname, 현재 경로의 쿼리스트링을 담고 있는 search등이 있다.

match

  • Route 컴포넌트에 있는 path 속성과 현재 url을 가지고 있어서 비교가능하다

param이용해서 라우터 묶어주기

  • 노드처럼 : 로 동적 params 받아올 수 있다.
  • URLSearchParams생성자 함수로 params에 있는 쿼리스트링 추출가능하다.
// 이렇게 하나하나 대입하면 많아서 복잡함
<BrowserRouter>
  <Link to="number-baseball">숫자</Link>
  <Link to="rock-scissors-paper">가위</Link>
  <Link to="lotto-generator">로또</Link>
  <div>
    <Route path="/number-baseball" component={NumberBaseball} />
    <Route path="/rock-scissors-paper" component={RSP} />
    <Route path="/lotto-generator" component={Lotto} />
  </div>
</BrowserRouter>

// 특정경로(여기선 game)으로 묶고 Route는 param(:) 이용해서 하나만 만들기
<BrowserRouter>
  <Link to="/game/number-baseball">숫자</Link>
  <Link to="/game/rock-scissors-paper">가위</Link>
  <Link to="/game/lotto-generator">로또</Link>
  <Link to="/game/index">게임</Link>
  <div>
    <Route path="/game/:name" component={GameMatcher} />
  </div>
</BrowserRouter>

// 조건절 이용해서 다르게 return하는 컨테이너 라우터 역할
const GameMatcher = ({location, match, history}) => {
  let urlSearchParams = new URLSearchParams(location.search.slice(1))
  console.log(urlSearchParams.get('name'), location, match, history);
  switch (match.params.name) {
    case "index":
      return <div>메인</div>;
    case "number-baseball":
      return <NumberBaseball />;
    case "rock-scissors-paper":
      return <RSP />;
    case "lotto-generator":
      return <Lotto />;
    default:
      return <div>일치하는 항목이 없습니다</div>;
  }
}

Switch, exact

  • 일치하는 라우터만 렌더링 해주는 Switch 컴포넌트
  • switch문처럼 위에서부터 순차적으로 비교해서 실행하므로 가장 복잡한 뎁스를 위로 작성해야 된다 -> /Text보다 /Text/exe가 위에 작성되야함
  • / 경로는 모든 컴포넌트가 가지고 있는 경로라서 두개가 겹쳐서 보이는 문제 발생
  • / 경로에는 exact 붙여주는거 공식처럼 적용하기(루트 라우터를 제일 아래에 작성해도 해결되지만 관용적으로 사용하자!)

<BrowserRouter>
  <Link to="/game/number-baseball?query=106&name=react">숫자</Link>
  <Link to="/game/rock-scissors-paper">가위</Link>
  <Link to="/game/lotto-generator">로또</Link>
  <Link to="/game/index">게임</Link>
  <div>
    <Switch>
      <Route exact path="/" component={GameMatcher} />
      <Route path="/game/:name" render={(props) => <GameMatcher {...props} />} />
    </Switch>
  </div>
</BrowserRouter>

NavLink 컴포넌트

  • Link컴포넌트처럼 a 태그 역할하지만 만약에 설정한 URL 이 활성화가 되면, 적용할 스타일이나 클래스를 지정 가능하다.
  • activeStyle: 클릭됬을때 적용될 클래스명
  • activeClassName: 클릭됬을때 적용될 클래스명
class App extends Component {
  go = () => { this.props.history.go(1);};
  goback = () => { this.props.history.go(-1);};
  goMain = () => { this.props.history.push("/");};

  render() {
    const active = {color: "red"};

    return (
      <div className="wrap">
        <nav>
          <ul>
            <li><NavLink exact={true} activeStyle={active} to="/">Main</NavLink></li>
            <li><NavLink activeStyle={active} to="/axios">AxiosData</NavLink></li>
            <li><NavLink activeStyle={active} to="/text">Text</NavLink></li>
          </ul>
        </nav>

        <Switch>
          <Route path="/axios" component={AxiosData} />
          <Route path="/text" component={Text} />
          <Route path="/" component={Main} />
        </Switch>
      </div>
    );
  }
}

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

[next.js] redux devtools 세팅법  (0) 2020.01.17
[Styled Components]syntex  (0) 2019.12.27
[styled-components] syntax  (0) 2019.12.26
[Custom Hooks] useInput, useFetch  (0) 2019.12.24
[총정리] useEffect(), useMemo(), useCallback()  (0) 2019.12.19