만두의 프론트엔드 찍먹 일기 - 페이지 라우팅편
오늘은 리액트의 페이지 라우팅에 대해서 공유해보도록하겠습니다!
🤔 페이지 라우팅이란?
경로에 따라 알맞은 페이지를 렌더링하는 과정입니다. 특정 url(/mypage, /edit 등)로 요청이 왔을 때 적절한 페이지(마이페이지, 게시글 편집 등)를 렌더링하는 것입니다.
💭 리액트의 페이지 라우팅은?
Multi Page Application(MPA)
MPA는 서버는 웹페이지를 HTML로 가지고 있고 요청이 들어왔을 때 요청 주소에 맞는 페이지를 응답하는 방식입니다. 그렇기 때문에 페이지를 이동할 때마다 서버에 요청을 보내고 웹페이지가 이동할 때 깜빡거리는 움직임이 생깁니다. 페이지 이동이 매끄럽지 않고 페이지 이동마다 요청을 보내기 때문에 서버 부하의 위험도 있습니다.
Single Page Application(SPA)
결론부터 말하자면 리액트는 SPA에 최적화되어 있습니다. 리액트 웹서버는 index.html 페이지와 컴포넌트나 기타 기능 등 자바 스크립트 파일들도 함께 존재합니다. 브라우저는 index.html을 먼저 렌더링하고 서버가 자바 스크립트 파일들을 하나의 파일로 합쳐 브라우저에 전달합니다. 이때 자바 스크립트 파일들을 하나로 묶는 작업을 Bundling이라고 하고 하나의 자바 스크립트 파일을 Bundle JS File이라고 합니다.
전체 페이지를 리렌더링하던 전통적인 MPA과 다르게 필요한 요소만 리렌더링하기 때문에 효율적입니다.
🏃♂️ 코드를 통해서 알아보자
먼저 npm을 사용해서 리액트에서 많이 사용하는 클라이언트 사이드 라우팅 라이브러리를 먼저 설치합니다.
$ npm i react-router-dom
그리고 App 컴포넌트를 <BrowserRouter>
로 감싸줍니다.
import { createRoot } from "react-dom/client";
import App from "./App.jsx";
import { BrowserRouter } from "react-router-dom";
createRoot(document.getElementById("root")).render(
<BrowserRouter>
<App />
</BrowserRouter>
);
Router
을 이용하여 요청 url과 컴포넌트를 매핑해 줍니다.
function App() {
return (
<Routes>
<Route path="/" element={<Home />} />
<Route path="/diary" element={<Diary />} />
<Route path="/new" element={<New />} />
<Route path="*" element={<Notfound />} />
</Routes>
);
}
export default App;
와일드 카드를 사용하면 매핑되는 url이 없을 때 해당 컴포넌트를 렌더링할 수 있습니다.
라우팅
링크를 통해서 라우팅
react-router-dom
의 Link
를 통해서 라우팅하는 예제입니다.
<Link to={"/"}>Home</Link>
<Link to={"/new"}>New</Link>
<Link to={"/diary"}>Diary</Link>
<a>
는 사용자가 클릭했을 때 서버에 요청을 보내고 페이지를 새로 로드하기 때문에 <Link>
를 사용합니다.
이벤트 핸들링을 통한 라우팅
커스텀 훅 useNavigate
를 통해서 렌더링합니다.
import { useNavigate } from "react-router-dom";
function App() {
const nav = useNavigate();
const onClickButton = () => {
nav("/new");
};
return (
<>
<button onClick={onClickButton}>New 페이지로 이동</button>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/diary" element={<Diary />} />
<Route path="/new" element={<New />} />
<Route path="*" element={<Notfound />} />
</Routes>
</>
);
}
동적 경로로 페이지 라우팅
<Route path="/diary/:id" element={<Diary />} />
🫨 정적 파일 저장 폴더에도 차이가 있어요!
Vite로 생성한 리액트 프로젝트 디렉토리에는 /public
과 /src/assets
가 있습니다. 이 둘의 차이가 무엇인지 알아봅시다!
저는 프론트엔드 빌드 도구로 Vite를 사용했습니다. Vite의 내부적으로 진행하는 이미지 최적화 설정때문에 두 정적 폴더의 작동방식에는 차이가 있습니다. 빌드 이후에 /public
에 저장된 정적 파일들은 url 형식으로 표기되는 반면, /src/assets
는 이미지를 String
타입으로 캐싱하여 데이터 uri 형식으로 표기됩니다. 캐싱된 이미지들은 새로고침하더라도 다시 불러오지 않기 때문에 속도가 매우 빠르지만, 이미지가 매우 많이 필요한 경우 전부 캐싱하게 되면 캐시 관리의 이유로 오히려 성능이 좋지 않을 수 있습니다.
🙏 글을 마치며
오늘은 리액트의 페이지 라우팅에 대해서 알아보았습니다. 렌더링은 비용이 많이 들기 때문에 이를 최적화하는 방안을 항상 고민하는게 어렵다고 생각됩니다. 성능을 고민하는게 흥미로워서 리액트에 재미를 붙여가는 것 같습니다. 💃