본문 바로가기
Frontend/React

새로운 라우팅 라이브러리, wouter

by 잘먹는 개발자 에단 2025. 4. 21.

- 아주 가벼운 라우터 라이브러리

- 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에서 바로 꺼내 쓰면 된다.