웹에서 페이지 이동(네비게이션) 의 원래 의미는 원래 서버에게 새로운 HTML 페이지를 요청하는 것이다.
URL을 바꾸면 항상 서버가 GET /xxx.html 같은 새 문서를 다시 내려보내는 방식.
그런데 React로 만든 SPA 에서는 이 방식이 아니다.
실제로는 페이지 전체를 새로 요청하지 않는데도 화면이 바뀐 것처럼 보이는 것이 목적이다.
따라서 React 안에서 “이동한다”는 것은:
HTML을 새로 받으러 서버로 이동하는 게 아니라,
클라이언트가 가진 UI 상태를 바꾸는 동작이다.
그리고 서버에 데이터를 요청해야 한다면
그건 라우터가 아니라 fetch / axios 같은 비동기 요청의 역할이다.
정리하면:
| 역할 | 주체 | 하는 일 |
|---|---|---|
| 라우팅(React Router) | 클라이언트 | 화면 전환, URL ↔ 컴포넌트 매핑 |
| 데이터 요청(fetch/axios) | 클라이언트 → 서버 | 데이터를 가져오는 유일한 “서버 통신” |
그래서 React Router는
이 UI 측 네비게이션 로직을 담당하는 라이브러리이다.
React Router는 React에서 페이지 이동(화면 전환)을 가능하게 해주는 라이브러리이다.
SPA(싱글 페이지 애플리케이션)는 화면이 바뀌어도 실제로는 HTML 페이지가 새롭게 로딩되지 않고,
자바스크립트가 컴포넌트만 교체하여 마치 페이지가 이동된 것처럼 보이게 만든다.
React Router는 “이 URL이면 이 화면을 보여줘”라는 규칙을 정의해 URL과 화면을 연결해준다. 이렇게 함으로써 새로고침 없이도 페이지가 전환된 것처럼 보이게 하고, 뒤로가기·즐겨찾기·직접 주소 입력 같은 브라우저 기본 기능도 정상적으로 사용할 수 있게 해준다.
/user/1 , /post/20 같은 동적 파라미터도 표현할 수 있다 프로젝트 안에서
npm install react-router-dom
| 이름 | 역할 |
|---|---|
| BrowserRouter | 라우터 기능을 전체 앱에 켜주는 태그 (최상단에 감싸는 역할) |
| Routes | 여러 Route 들을 묶는 컨테이너 |
| Route | 특정 주소(path)에 어떤 컴포넌트를 보여줄지 정의 |
| Link | a태그 대체. 페이지 전체 새로고침 없이 다른 주소로 이동 |
| Outlet | 중첩 라우트에서 “자식 컴포넌트가 그려질 자리” |
<BrowserRouter>
<Routes>
<Route path="/" element={<Home/>}/>
<Route path="/about" element={<About/>}/>
<Route path="/contact" element={<Contact/>}/>
</Routes>
</BrowserRouter>
이렇게 하면
/ → Home 컴포넌트/about → About 컴포넌트/contact → Contact 컴포넌트중첩 라우트는
상위 화면은 유지하고 그 안의 일부만 바뀌게 할 때 사용한다.
부모 컴포넌트에서 <Outlet />을 넣어두면
자식 Route 의 화면이 그 자리에 표시된다.
예: /products → /products/car → /products/bike
<Route path="/products" element={<Products/>}>
<Route path="car" element={<CarProducts/>}/>
<Route path="bike" element={<BikeProducts/>}/>
</Route>
NavLink는 Link와 거의 같지만
지금 보고 있는 화면과 같은 URL이면 자동으로 “선택된 상태” 로 구분해준다.
import { NavLink } from "react-router-dom";
const navStyle = ({ isActive }) => ({
fontWeight: isActive ? "bold" : "normal",
color: isActive ? "blue" : "black"
});
function NavMenu() {
return (
<nav>
<NavLink to="/" style={navStyle}>Home</NavLink> |{" "}
<NavLink to="/about" style={navStyle}>About</NavLink> |{" "}
<NavLink to="/contact" style={navStyle}>Contact</NavLink>
</nav>
);
}
주소 일부를 변수처럼 사용할 수 있다.
예: /user/3
<Route path="/user/:userId" element={<User/>}/>
페이지 내부에서 값을 읽을 때 이렇게 하면 userId 는 "3" 같은 문자열 값이 된다.
const { userId } = useParams();
| 상황 | 어디에 넣는게 맞나? |
|---|---|
| 게시글 번호 / 유저 ID 같은 식별자 | path param :id |
| 검색, 정렬, 페이지 번호 | query string ?page=2&sort=desc |
| 공유 필요 없는 임시 값 (내부 전용) | router state |
| 페이지 틀(layout) | parent Route + <Outlet/> |
이 4개 원칙만 유지하면 라우팅 구조는 깔끔해진다.