리액트는 SPA(Single Page Application)로 구성되어 있습니다.
그래서 페이지 전환이 파일로 이동하는 것이 아닌 한 페이지내에서 컴포넌트를 변경하는 방식입니다.
경로를 만들어준다!
react는 SPA(단일 페이지)이기 때문에 history 관리가 필요하다.
그래서 사용자가 요청한 URL에 따라서 다른 결과물을 렌더링을 해주어야 한다.
리액트의 페이징 처리를 도와주는 라이브러리입니다.
React-Router는 설정된 url에 따라 컴포넌트를 변경해줍니다.
우선 패키지를 설치합니다.
npm install react-router-dom
npm install @types/react-router-dom // typescript 사용 시 추가로 실행
or
yarn add react-router-dom
yarn add @types/react-router-dom // typescript 사용 시 추가로 실행
// HomeButton.jsx
import { useHistory, useLocation } from "react-router-dom";
function HomeButton() {
let history = useHistory();
let location = useLocation();
function handleClick() {
history.push("/home");
console.log(location.pathname);
}
return (
<button type="button" onClick={handleClick}>
Go home
</button>
);
}
// index.jsx
import React from "react";
import ReactDOM from "react-dom";
import {
BrowserRouter as Router,
Switch,
Route,
useParams,
useRouteMatch
} from "react-router-dom";
function BlogPost() {
let { slug } = useParams();
const match = useRouteMatch({
path: '/BLOG/:slug/',
strict: true,
sensitive: true
})
return <div>{match ? <div>Now showing post {slug}</div> : <NotFound />}</div>
}
ReactDOM.render(
<Router>
<Switch>
<Route exact path="/">
<HomePage />
</Route>
<Route path="/blog/:slug">
<BlogPost />
</Route>
</Switch>
</Router>,
node
);
<Router>
: react-router를 사용하려면 사용할 컴포넌트 겉에 한번 감싸주고 사용해야한다. 일반적으로 아래 라우터 중 하나를 사용.<BrowserRouter>
: HTML5 History API 사용. 주소만 바꾸고 페이지는 다시 불러오진 않는다.<HashRouter>
: 옛날 브라우저 전용. 주소:8080/#/game 이런식으로 주소 사이 hash(#)이 붙는다.<MemoryRouter>
: 브라우저의 주소와 무관하다.(일체 건들이지 않음) 브라우저가 아닌 환경에서 쓰기 좋다. ex) 테스트 환경, 임베디드 웹앱, 리액트 네이티브 등<StaticRouter>
: 서버에서 주로 사용<Switch>
: 하위에 라우터 중 하나를 선택. 라우트들을 이 컴포넌트에 감싸면 매칭되는 첫번째 라우트만 보여주고 나머지는 보여주지 않는다.import { Route } from "react-router";
let routes = (
<div>
<Route path="/about">
<About />
</Route>
<Route path="/:user">
<User />
</Route>
<Route path="*"> // 요청경로에 매칭되는 컴포넌트가 없는 경우 모두 처리
<NoMatch />
</Route>
</div>
);
<Link>
: a 태그처럼 페이지 이동에 사용. 옵션을 주어 다양하게 사용할 수 있다. ( a 태그와 같이 페이지를 새로 불러오진 않는다.)<NavLink>
: 기능에 active class name을 옵션으로 사용할 수 있다. (activeClassName => 선택된 link를 acitve 효과를 줄 수 있다.)
<Link to="/courses?sort=name" />
// 다양한 옵션 설정
<Link
to={{
pathname: "/courses", // 이동할 path
search: "?sort=name", // query 파라미터. 여기까지 위에 사용된 Link와 사용법이 같다.
hash: "#the-hash", // URL에 넣을 해시값
state: { fromDashboard: true } // history pushState의 state와 같다. location에 전달할 state
}}
/>
// to 옵션에 함수 사용 이외에 다양하게 사용할 수 있다.
<Link to={location => ({ ...location, pathname: "/courses" })} />
<NavLink to="/faq" activeClassName="selected">
FAQs
</NavLink>
<Route>
: 요청 경로와 렌더링할 컴포넌트를 설정<Route path="/" exact component={Home} />
// 여기서 exact 옵션은 location과 정확하게 일치하는 경우에만 render 하도록 설정하는 옵션. false는 exact를 사용하지 않으면 된다.
// 추가로 strict 옵션도 있는데, 이 옵션은 path 맨 뒤에 '/'의 유무에 따라 페이지가 매칭된다.
// 예를 들어, 두 가지 옵션을 동시에 주면 등록된 path는 '/home' 일 때 '/home/'으로 접속하면 '/home' path에 등록된 컴포넌트는 render되지 않는다.
<Redirect>
: 요청 경로를 다른 경로로 리다이렉션한다<Redirect to="/somewhere/else" />
// 아래와 같이 요청경로를 다른경로로 이동시켜 줄 수 있다.
<Switch>
<Redirect exact from="/" to="/home" />
<Route path="/home">
<Home />
</Route>
<Route path="/about">
<About />
</Route>
</Switch>
<Router>
<div>
<ul>
<li>
<Link to="/">Home</Link> {/* '/' 로 path 이동 */}
</li>
<li>
<Link to="/about">About</Link> {/* '/about' 로 path 이동 */}
</li>
<li>
<Link to="/dashboard">Dashboard</Link> {/* '/dashboard' 로 path 이동 */}
</li>
</ul>
<hr />
<Switch>
<Route exact path="/"> {/* '/' path에 <Home /> 컴포넌트 등록 */}
<Home />
</Route>
<Route path="/about"> {/* '/about' path에 <About /> 컴포넌트 등록 */}
<About />
</Route>
<Route path="/dashboard"> {/* '/dashboard' path에 <Dashboard /> 컴포넌트 등록 */}
<Dashboard />
</Route>
</Switch>
</div>
</Router>
참고