페이지 라우팅 소개
전통적인 웹 어플리케이션은 서버 측에서 여러 개의 html 파일을 가지고 있다가, 브라우저가 요청하면 html 파일을 렌더링하여 보내주는 방식을 취했었다. 이렇게 서버 측에서 html 파일들을 가지고 있는 것을 MPA (Multi Page Application) 라고 부르고, 서버 측에서 렌더링하는 방식을 SSR (Server Side Rendering) 이라고 한다. 하지만 이런 방식은 클라이언트가 새로운 페이지를 요청할 때마다 화면 전체가 새로고침 되고, 서버 측은 여러 요청을 받으면 부하가 심해진다.
그렇지만 리액트는 빠른 페이지 전환을 자랑한다. 그 이유는 무엇일까? 왜냐하면 리액트는 서버 측에서 하나의 페이지, index.html만 가지고 있는 SPA (Single Page Application) 방식이고, 나머지 자바스크립트 파일들은 번들화하여 통째로 브라우저에게 전달한다. (그렇기에 리액트 앱을 전달한다고 볼 수 있다.) 리액트는 컴퍼넌트 기반이기 때문에, 브라우저는 페이지를 이동하더라도 화면을 통째로 리렌더링하지 않고, 변경된 컴퍼넌트만 리렌더링하여 비용을 줄일 수 있다. 이렇게 클라이언트 측에서 렌더링이 이루어지는 것을 CSR (Client Side Rendering) 이라고 한다.
라우팅 설정하기
npm i react-router-dom // 콘솔창에 입력
Routes, Route 컴퍼넌트를 이용할 수 있게 된다.
// main.jsx
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App.jsx";
import { BrowserRouter } from "react-router-dom";
createRoot(document.getElementById("root")).render(
<BrowserRouter>
<App />
</BrowserRouter>
);
BrowserRouter 태그로 App 태그를 감싸주면, 앱 내의 모든 컴퍼넌트들이 브라우저의 주소에 접근 가능하게 된다.
// App.jsx
import "./App.css";
import { Routes, Route } from "react-router-dom";
import Home from "./pages/Home";
import Diary from "./pages/Diary";
import New from "./pages/New";
import Notfound from "./pages/Notfound";
function App() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/new" element={<New />} />
<Route path="/diary" element={<Diary />} />
<Route path="*" element={<Notfound />} />
</Routes>
);
}
export default App;
path에서 "/"는 현재 브라우저의 주소, element에는 해당 주소에서 보일 컴퍼넌트가 들어간다. 참고로 Routes 컴퍼넌트 안에는 Route 컴퍼넌트만 들어갈 수 있다. (얘네가 태그인가? 했는데 브라우저가 아닌 리액트에 의해 해석되고 동작하는 컴퍼넌트이다.)
페이지 이동
import "./App.css";
import { Routes, Route, Link, useNavigate } from "react-router-dom";
import Home from "./pages/Home";
import Diary from "./pages/Diary";
import New from "./pages/New";
import Notfound from "./pages/Notfound";
function App() {
const nav = useNavigate();
const onClickButton = () => {
nav("/new");
};
return (
<>
<div>
<Link to={"/"}>Home</Link>
<Link to={"/new"}>New</Link>
<Link to={"/diary"}>Diary</Link>
</div>
<button onClick={onClickButton}>New 페이지로 이동</button>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/new" element={<New />} />
<Route path="/diary" element={<Diary />} />
<Route path="*" element={<Notfound />} />
</Routes>
</>
);
}
export default App;
링크를 통해서나, 버튼 클릭같은 이벤트를 통해서 페이지 이동이 발생할 때, 리액트의 컴퍼넌트를 이용할 수 있다. 바로 Link, useNavigate 컴퍼넌트를 이용해서이다. useNavigate 같은 경우 nav 변수에 함수를 저장한다. 왜냐하면 함수를 반환하는 리액트 훅이기 때문에 먼저 저장하고 실행해야 한다. 이벤트 핸들러에서 nav 변수가 인수로 이동할 주소를 가지도록 하면 된다.
요렇게 리액트 컴퍼넌트를 이용하지 않고 a 태그를 이용한다면, 링크 클릭 시 페이지 전체가 새로고침 된다. 그러므로 리액트에서는 링크를 사용할 때는 Link 컴퍼넌트, 특정 이벤트 발생 시 페이지를 이동해야 할 때는 useNavigate 컴퍼넌트를 이용하는 것이 좋다.
동적 경로

동적 경로에는 URL Parameter, Query String 두 가지 방법이 있다. 여기서 동적 경로란 동적 데이터를 포함하고 있는 경로를 말한다. 쉽게 말해 주소 안에 변수가 포함되어 있다고 보면 된다. 우리가 진행할 프로젝트에선 URL 파라미터를 이용할 것이다.
// App.jsx 내 일부
<Routes>
<Route path="/" element={<Home />} />
<Route path="/new" element={<New />} />
<Route path="/diary/:id" element={<Diary />} />
<Route path="*" element={<Notfound />} />
</Routes>
동적 데이터를 넣는 방법은, 동적 데이터 앞에 : 를 붙인다. 그럼 브라우저에서 입력한 동적 데이터가 URL 파라미터로 들어간다.
// Diary.jsx
import { useParams } from "react-router-dom";
const Diary = () => {
const params = useParams();
console.log(params);
return <div>{params.id}번 일기입니다</div>;
};
export default Diary;
해당 URL 파라미터를 이용하는 방법은, 먼저 useParams 컴퍼넌트를 임포트 해온다. 변수에 함수를 생성해주면, 객체를 받아오기 때문에 프로퍼티로 접근하면 된다.
추가로.. 쿼리 스트링을 이용하는 방법도 첨부한다. 브라우저 주소http://localhost:5173/?value=hello 을 입력하면 hello가 콘솔에 출력된다.
import { useSearchParams } from "react-router-dom";
const Home = () => {
const [params, setParams] = useSearchParams();
console.log(params.get("value"));
return <div>Home</div>;
};
export default Home;
'프론트엔드 > 한 입 크기로 잘라먹는 리액트' 카테고리의 다른 글
| React.js - 웹 스토리지 이용하기 (0) | 2025.03.01 |
|---|---|
| React.js - Context란, Context 사용하기, Context 분리하기 (0) | 2025.02.07 |
| React.js - useMemo와 연산 최적화, React.memo와 컴포넌트 렌더링 최적화, useCallback과 함수 재생성 방지 (0) | 2025.02.05 |
| React.js - useReducer 소개 (0) | 2025.02.04 |
| React.js - 카운터 앱, State Lifting (0) | 2025.01.30 |