router

» REACT

router란?

  • SPA란?
    Single Page Application의 약자로써 페이지가 1개인 어플리케이션이라는 뜻

  • 라우팅이란?
    어떤 주소에 어떤 UI를 보여줄지 규칙을 정하는 것

react-router-dom이란?

페이지를 이동할때 react-router-dom이란 것을 이용한다

  • router 적용
    라우터를 사용하기 위해선 최상위 컴포넌트를 묶고 시작해야함

    import React from "react";
    import App from "./App";
    import { BrowserRouter } from "react-router-dom";
    
    function Root() {
      return (
        <BrowserRouter>
          <App />
        </BrowserRouter>
      );
    }
    
    export default Root;
    
  • react-router-dom 패키지

    패키지 사용처
    react-router 웹 && 앱
    react-router-dom
    react-router-native
  • 설치방법
    react-router-dom을 기준으로 작성되었습니다

    npm에서 설치

    npm i react-router-dom
    

    import 시키기

    import { BrowserRouter, Route, Link, Switch } from "react-router-dom";
    

    import된 4가지들은 각각

    router mean
    BrowerRouter history API를 사용해 URL과 UI를 동기화하는 라우터
    Route 컴포넌트의 속성에 설정된 URL과 현재 경로가 일치하면 해당하는 컴포넌트, 함수를 렌더링
    Link HTML에 ‘a’태그와 비슷하며 to속성에 설정된 링크로 이동함(href와 유사).
    history 스택에 저장됨
    Switch 자식 컴포넌트 Route 또는 Redirect 중 매치되는 첫번째 요소를 랜더링.
    Switch를 사용하면 BrowerRouter만 사용할 때와는 다르게 하나의 매칭되는 요소만 랜더링한다는 점을 보장해줌.
    사용하지 않을 경우 매칭되는 모두를 랜더링함
  • 사용 방식

    <Route path='주소규칙' component={보여주고싶은컴포넌트}>
    
  • exact
    Route에 exact를 넣으면 해당 경로와 완전히 일치할때만 보여줌

    // 예시
    <Route path="/" component={Home} exact />
    

페이지주소 형식

  • 파라미터 특정 id나 이름을 가지고 조회할 때 주로 사용됨

    /profiles/kaen

  • 파라미터 예시 /profiles/kaen처럼 해당 값을 받아오기 위한 예시

    // Profile.js
    
    // 프로필에서 사용 할 데이터
    const profileData = {
      kaen: {
        name: "이성훈",
        description: "Frontend Developer?",
      },
      harry: {
        name: "해리포터",
        description: "이마에 번개 타투",
      },
    };
    
    const Profile = ({ match }) => {
      // 파라미터를 받아올 땐 match 안에 들어있는 params 값을 참조합니다.
      const { username } = match.params;
      const profile = profileData[username];
      if (!profile) {
        return <div>존재하지 않는 유저입니다.</div>;
      }
      return (
        <div>
          <h3>
            {username}({profile.name})
          </h3>
          <p>{profile.description}</p>
        </div>
      );
    };
    
    //App.js
    
    // ':파라미터'형식으로 username을 Profile.js에게 전달해줌
    <Route path="/profiles/:username" component={Profile} />
    
  • 쿼리
    어떤 키워드를 검색하거나 요청할 때 필요한 옵션을 전달할 때 사용됨

    about?details=true

  • 쿼리 예시
    쿼리는 라우트 컴포넌트에게 location 객체를 props로 전달해줌

    // location 예시
    {
      key: 'ac3df4', // not with HashHistory!
      pathname: '/somewhere'
      search: '?some=search-string',
      hash: '#howdy',
      state: {
        [userDefined]: true
      }
    }
    

    search 값을 확인해야 하는데 값이 문자열 형태이므로 객체 형태로 변환해줘야 하는데 이때 쉽게 작업하는 방법이 qs라이브러리를 사용하는 것이다.

    yarn add qs
    

    qs 라이브러리 사용한 예시

    import React from "react";
    // qs 불러오기
    import qs from "qs";
    
    const About = ({ location }) => {
      // 받아온 loaction search값 파싱(추출)
      // parse는 string 객체를 json 객체로 변환시켜주는 메소드
      const query = qs.parse(location.search, {
        // 쿼리에 ?(물음표)를 제거해주는 역할
        ignoreQueryPrefix: true,
      });
      const detail = query.detail === "true"; // 쿼리의 파싱결과값은 문자열입니다.
    
      return (
        <div>
          <h1>소개</h1>
          <p>
            이 프로젝트는 리액트 라우터 기초를 실습해보는 예제 프로젝트랍니다.
          </p>
          {detail && <p>추가적인 정보가 어쩌고 저쩌고..</p>}
        </div>
      );
    };
    
    export default About;
    

서브 라우트

라우트 내부의 라우트를 만드는 것을 의미하며 그냥 컴포넌트를 만들어서 그 안에 또 Route 컴포넌트를 렌더링하면 됨

  • render
    컴포넌트가 아니라 JSX 자체를 렌더링해줄 수 있으며 상위 영역에서 props 같은 값들을 전달해줄 수 있음

    <Route
      path="/profiles"
      exact
      render={() => <div>유저를 선택해주세요.</div>}
    />
    

라우터 부가기능

  • history 객체
    라우트로 사용된 컴포넌트에게 전달되는 match, location과 같은 props 중 하나로써 컴포넌트 내에 구현하는 메소드에서 라우터에 직접 접근할 수 있음

    이탈 방지, 뒤로 가기 등등

    // HistorySample.js
    function HistorySample({ history }) {
      const goBack = () => {
        history.goBack();
      };
    
      const goHome = () => {
        history.push("/");
      };
    
      useEffect(() => {
        console.log(history);
        const unblock = history.block("정말 떠나실건가요?");
        return () => {
          unblock();
        };
      }, [history]);
    
      return (
        <div>
          <button onClick={goBack}>뒤로가기</button>
          <button onClick={goHome}>홈으로</button>
        </div>
      );
    }
    
    • history 객체 안의 값

      // 라우터에서 가장 마지막에 발생한 액션이 무엇인지 알려줌
      action: "PUSH"
      // 사용자가 이탈할때 발생
      block: ƒ block(prompt)
      // 로케이션 형태의 값을 가지고 주소를 만드는 형태
      createHref: ƒ createHref(location)
      // 앞 혹은 뒤로
      go: ƒ go(n)
      // 뒤로가기
      goBack: ƒ goBack()
      // 앞으로 가기
      goForward: ƒ goForward()
      // 방문기록 길이
      length: 50
      // 경로 변동이 생겼을때 특정함수 호출
      listen: ƒ listen(listener)
      // 현재 자신이 있는 경로에 대한 정보
      location: {pathname: "/profiles", search: "", hash: "", state: undefined, key: "rmiowg"}
      // 특정 주소로 이동
      push: ƒ push(path, state)
      // 특정 주소로 이동하지만 방문기록을 남기지 않음
      replace: ƒ replace(path, state)
      __proto__: Object
      
  • withRouter
    라우터 컴포넌트가 아닌 곳에서 match, location, history를 사용 주로 라우트로 사용되지 않은 컴포넌트에서 조건부로 이동을 해야될때 자주 사용됨 로그인 성공했을때 혹은 실패했을때

    import React from "react";
    // withRouter 호출
    import { withRouter } from "react-router-dom";
    
    function WithRouterSample({ location, match, history }) {
      return (
        <div>
          <h4>location</h4>
          {/* JSON.stringify는 JSON을 문자열 형태로 변경해주는 것 */}
          <textarea value={JSON.stringify(location, null, 2)} readOnly />
          <h4>match</h4>
          <textarea value={JSON.stringify(match, null, 2)} readOnly />
          <button onClick={() => history.push("/")}>홈으로</button>
        </div>
      );
    }
    
    // widthRouter로 감싸줌
    export default withRouter(WithRouterSample);
    
  • switch
    여러 라우트 중 가장 먼저 매칭된 하나만 보여줌 페이지를 못찾았을때 사용하면 유용함

    // Switch 호출
    import { Switch, Route, Link } from "react-router-dom";
    
    // Switch로 감싸줘서 사용
    <Switch>
      <Route path="/" exact={true} component={Home} />
      <Route path="/about" component={About} />
      <Route path="/profiles" component={Profiles} />
      <Route path="/history" component={HistorySample} />
      <Route
        // path 를 따로 정의하지 않으면 모든 상황에 렌더링됨
        render={({ location }) => (
          <div>
            <h2>이 페이지는 존재하지 않습니다:</h2>
            <p>{location.pathname}</p>
          </div>
        )}
      />
    </Switch>;
    
  • NavLink
    만약 현재 경로와 Link에서 사용하는 경로가 일치하는 경우 특정 스타일 혹은 클래스를 적용할 수 있는 컴포넌트

    <NavLink
      to="/profiles/velopert"
      // 스타일
      activeStyle=
      // 클래스
      activeClassName={nav_link}
      // 해당 함수가 트루가 되면 동작
      isActive={(match, location) => {
        return true;
      }}
    >
      테스트
    </NavLink>
    
  • useReactRouter
    withRouter대신 Hook을 사용해서 구현할 수 있는 라이브러리

    설치

    yarn add use-react-router
    
    // 호출
    import useReactRouter from "use-react-router";
    
    function RouterHookSample() {
      // 조회할 것들
      const { history, location, match } = useReactRouter;
      console.log({ history, location, match });
      return null;
    }
    
    export default RouterHookSample;