- 아주 가벼운 라우터 라이브러리
- react-router가 너무 무겁다 싶을 때, 혹은 번들 사이즈를 작게 유지하고 싶을 때 사용하면 좋음.
## 특징
- 번들사이즈 약 1kb
- 훅 기반 : useLocation, useRoute등으로만 라우팅을 처리
- jsx 컴포넌트 없이도 ok : Route, Switch 컴포넌트가 있지만, 사실 훅만으로 충분
- SSR 지원
- 프레임워크 독립적 : React외 Preact, Inferno 등에도 쓸 수 있고
- 의존성 제로 : 리액트 외에 추가 의존 패키지 없음.
npm install wouter
### 기본 사용법
1. 라우터 감싸기
// App.tsx
import { Router } from 'wouter';
function App() {
return (
<Router>
<MainLayout />
</Router>
);
}
2. Route 컴포넌트
import { Route } from 'wouter';
import Home from './pages/Home';
import About from './pages/About';
function MainLayout() {
return (
<>
<nav>
<a href="/">Home</a>
<a href="/about">About</a>
</nav>
{/* 경로에 따라 컴포넌트 렌더링 */}
<Route path="/" component={Home} />
<Route path="/about" component={About} />
</>
);
}
3. Link 컴포넌트
import { Link } from 'wouter';
function Nav() {
return (
<nav>
<Link href="/">Home</Link>
<Link href="/about">About</Link>
</nav>
);
}
4. useLocation 훅
- 현재 경로 정보와 변경함수 가져올 수 있음
import { useLocation } from 'wouter';
function MyComponent() {
const [location, setLocation] = useLocation();
return (
<div>
<p>현재 경로: {location}</p>
<button onClick={() => setLocation('/about')}>
About로 이동
</button>
</div>
);
}
### 동적 라우팅 ( 파라미터 )
import { Route, useRoute } from 'wouter';
function UserProfile() {
// /user/:id 에서 id 추출
const [match, params] = useRoute('/user/:id');
// params.id 가 URL 세그먼트
if (!match) return <p>유저를 찾을 수 없어요.</p>;
return <p>유저 ID: {params.id}</p>;
}
// 라우트 설정
<Route path="/user/:id" component={UserProfile} />
### 여러 경로에 매칭
- react-router의 switch와 이름만 비슷
import { Switch, Route } from 'wouter';
<Switch>
<Route path="/login" component={Login} />
<Route path="/signup" component={Signup} />
{/* 위 두 개 모두 아니면 Home */}
<Route>
<Home />
</Route>
</Switch>
### 고급기능
* 리다이렉트
import { Redirect } from 'wouter';
function PrivatePage() {
const user = useUser();
if (!user) return <Redirect to="/login" />;
return <Dashboard />;
}
❗️ 주의사항
- 매칭 순서는 선언 순서이다. <Switch>안에서도 위에서부터 내려오면서 제일 먼저 맞는 라우트가 렌더링된다.
### react-router 와의 대비점
* wouter의 useLocation이 제공하는 setLocation 함수는 내부적으로 react router의 useNavigate(path, options)처럼 state 객체를 넘기는 api를 지원하지 않는다.
따라서 react-router 에서 처럼
// React Router (예시)
const navigate = useNavigate();
navigate("/dashboard", { state: { foo: "bar" } });
이런 식으로 데이터를 직접 전달할 수 없음.
* 그렇다면 어떻게 넘겨야 하는가?
1. URL 파라미터, 쿼리스트링에 껴서 보내기
- 경로 파라미터의 경우
// 보낼 때
setLocation(`/menus/${menu.id}/edit`);
// 받을 때
import { useRoute } from "wouter";
const [match, params] = useRoute("/menus/:id/edit");
if (match) {
console.log("편집할 메뉴 ID:", params.id);
}
- 쿼리 스트링의 경우
// 보낼 때 (데이터를 JSON 직렬화해 쿼리에 실을 수도 있고,
// 단순 키=값 페어로 쪼개서 실어도 됩니다)
const data = encodeURIComponent(JSON.stringify(menu));
setLocation(`/menus/edit?data=${data}`);
// 받을 때 (location 훅으로 전체 URL 받아서 파싱)
import { useLocation } from "wouter";
const [loc] = useLocation();
const query = new URLSearchParams(loc.split("?")[1]);
const raw = query.get("data");
const menu = raw ? JSON.parse(decodeURIComponent(raw)) : null;
2. 전역 상태 관리 / Context API 사용하기
- React Context, Recoil/Zustand/Jotai 같은 상태 관리 라이브러리를 사용해서 “편집할 메뉴” 객체를 전역에 저장하면, 라우팅에서는 단순히 경로만 바꾸고
// 예: 편집 메뉴를 Context에 set
menuContext.setEditingMenu(menu);
setLocation("/menus/edit");
다른 페이지(MenusEditPage)에서는 Context에서 바로 꺼내 쓰면 된다.
'Frontend > React' 카테고리의 다른 글
서비스 배포 케이스1 (1) | 2025.06.27 |
---|---|
Concurrent Mode(Concurrent Rendering)와 Suspense를 활용해 비동기 UI를 구성하는 방법과, 이 패턴의 장단점은 무엇인가요? (0) | 2025.03.21 |
React Fiber 아키텍처는 무엇이고, React reconciliation과정에서 어떤 역할을 하는지 설명하세요. (0) | 2025.03.21 |
React 18 ) useTransition (0) | 2025.03.18 |
React 19 ) useActionState( 구 useFormState ) (0) | 2025.03.18 |