본문 바로가기

React

[React 강의노트] react router

반응형

SPA 

- 라우팅을 클라이언트가 담당

- 라우팅이란? 어떤 주소에 어떤 UI를 보여줄지? 

 

react-router

- 컴포넌트 기반으로 라우팅

 

리액트 라우터에서 사용되는 주요 컴포넌트

 BrowserRouter

- HTML5 History API 사용

- 주소만 바꾸고 페이지는 다시 불러오진 않음

 

HashRouter

- example.com/#/path/to/route

- #을 사용함. 못생김, 옛날 브라우저 전용

 

MemoryRouter

- 브라우저의 주소와 무관, 일체 건들이지 않음

- 테스트 환경, 임베디드 웹앱, 리액트 네이티브 등에서 사용

 

StaticRouter

- 서버사이드 렌더링에서 사용하는 용도

 

Route

- 라우트를 정의할 때 사용하는 컴포넌트

 

Link

- 사용한 Router의 주소를 바꿈, a 태그지만 새로고침 안됨

 

 

 

SSR

 

CSR

 

 

//index.js

import { BrowserRouter } from "react-router-dom";

ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById("root")
);


//App.js

import React from "react";
import { Route, Link } from "react-router-dom";
import About from "./About";
import Home from "./Home";

function App() {
  return (
    <div>
      <ul>
        <li>
          <Link to="/">홈</Link>
        </li>
        <li>
          <Link to="/about">소개</Link>
        </li>
      </ul>
      <hr />
      <Route path="/" component={Home} exact />
      <Route path="/about" component={About} />
    </div>
  );
}

export default App;

 

 

파라미터와 쿼리

- 주소를 통해 동적인 값을 받아오는 형태

- 파라미터를 받아올 땐 match 안에 들어있는 parmas값을 참조한다.

 

파라미터

 

//App.js
<Route path="/profile/:username" component={Profile} />


//profile.js
import React from "react";

const ProfileDate = {
  heeyeon: {
    name: "희연",
    description: "Frontend Engineer",
  },
  homer: {
    name: "심슨",
    description: "뭐여이게",
  },
};

function Profile({ match }) {
  const { username } = match.params;
  const profile = ProfileDate[username];

  if (!profile) {
    return <div>존재하지 않는 사용자입니다.</div>;
  }

  return (
    <div>
      <h3>
        {username} ({profile.name})
      </h3>
      <p>{profile.description}</p>
    </div>
  );
}

export default Profile;

 

 

쿼리

 

- qs 라이브러리 설치해서 추출

- 쿼리는 route 컴포넌트에게 props 전달되는 location 객체에 있는 search값에서 읽어올 수 있다.

+ search값은 문자열 형태로 되어있기 때문에 객체로 변환하기 위해 qs라이브러리를 사용하여 쉽게 할 수 있다.

 

import React from "react";
import qs from "qs";

function About({ location }) {
  const query = qs.parse(location.search, {
    ignoreQueryPrefix: true, //? 없애고 보여줌
  });

  console.log(query);

  return (
    <div>
      <h1>소개</h1>
      <p>이 프로젝트는 리액트 라우터 기초를 실습하는 프로젝트 입니다.</p>
    </div>
  );
}

export default About;

 

 

응용

 

import React from "react";
import qs from "qs";

function About({ location }) {
  const query = qs.parse(location.search, {
    ignoreQueryPrefix: true, //? 없애고 보여줌
  });

  const detail = query.detail === "true"; //string으로 받아오기때문에 무조건 string

  console.log(query);

  return (
    <div>
      <h1>소개</h1>
      <p>이 프로젝트는 리액트 라우터 기초를 실습하는 프로젝트 입니다.</p>
      {detail && <p>detail 값이 true입니다.</p>}
    </div>
  );
}

export default About;

 

 

서브라우트 만들기

 

서브라우트란? 라우트안에 들어있는 또다른 라우트

 

import React from "react";
import { Route, Link } from "react-router-dom";
import Profile from "./Profile"; //사용자 정보들어있음

//서브라우트 만들기
function Profiles() {
  return (
    <div>
      <h3>사용자 목록</h3>
      <ul>
        <li>
          <Link to="/profiles/heeyeon">heeyeon</Link>
        </li>
        <li>
          <Link to="/profiles/homer">homer</Link>
        </li>
      </ul>
      <Route
        path="/profiles"
        exact
        render={() => <div>사용자를 선택해주세요</div>}
      />
      <Route path="/profiles/:username" component={Profile} />
    </div>
  );
}

export default Profiles;

 

- 특정 경로에 탭이 있는 경우

- 태그 선택시

 

 

리액트 라우터 부가기능

- history 객체 : 

push와 replace의 차이점

push- 기록이 남음

replace- 방문기록이 남지 않음

 

- history.block() :  페이지 나가기 전 물어보기, 이탈 방지 

 

useEffect(() => {
  console.log(history);
  //페이지 나가기 전 물어보기, 이탈방지
  const unblock = history.block("떠나실건가욤?");
  return () => {
    unblock();
  };
}, [history]);

 

 

- withRouter : 라우터 컴포넌트가 아닌 곳에서 match, location, history 사용

 

import React from "react";
import { withRouter } from "react-router-dom";

//withRouter : 라우터 컴포넌트가 아닌 곳에서 match, location, history 사용
function WithRouterSample({ match, location, history }) {
  return (
    <div>
      <h4>location</h4>
      <textarea value={JSON.stringify(location, null, 2)} readOnly></textarea>
      <h4>match</h4>
      <textarea value={JSON.stringify(location, null, 2)} readOnly></textarea>
      <button onClick={() => history.push("/")}>홈으로</button>
    </div>
  );
}

export default withRouter(WithRouterSample);

 

- ex) 로그인 후 특정경로 가기

 

 

- switch : 여러가지 라우터중 가장 먼저 매칭되는 라우터 하나만 보여줌

 

      <Switch>
        <Route path="/" component={Home} />
        <Route path="/about" component={About} />
        <Route path="/profiles" component={Profiles} />
        <Route path="/history" component={HistorySample} />
      </Switch>

 

- exact가 없을 경우 가장 먼저 매칭된 Home 컴포넌트만 계속 보여줌

 

<Switch>
  <Route path="/" component={Home} exact />
  <Route path="/about" component={About} />
  <Route path="/profiles" component={Profiles} />
  <Route path="/history" component={HistorySample} />
  <Route
    render={({ location }) => (
      <div>
        <h2>이 페이지는 존재하지 않습니다.</h2>
        <p>{location.pathname}</p>
      </div>
    )}
  />
</Switch>

 

- 아무것도 찾지 못할 경우 아래까지 내려가서 404 페이지 만들기. 404 페이지 만들 때 유용

 

 

NavLink : 현재 주소와 일치한다면 스타일 바꾸기 

 

<NavLink
  to="/profiles/homer"
  activeStyle={{ background: "black", color: "white" }}
  activeClassName="active" //classname 주기
  //isActive 함수 true 반환시 특정스타일주기
>
  homer
</NavLink>