SPA(Single Page Application)란 서버로부터 완전한 새로운 페이지를 불러오지 않고 페이지 갱신에 필요한 데이터만 받아 그 정보를 기준으로 현재의 페이지를 업데이트함으로써 사용자와 소통하는 웹 어플리케이션이나 웹 사이트를 말한다.
HTML 문서 전체가 아니라 업데이트에 필요한 데이터만 받아, JavaScript가 이 데이터를 조작하여 생성한 HTML 요소를 화면에 보여주는 개발 방식을 적용했다.
명령어
npm install react-router-dom@^버전
타입 스크립트 사용 시 추가 설치
npm install react-router-dom @types/react-router-dom
package.json
파일의 dependencies
항목에 react-router-dom
이라는 라이브러리가 등록된 것을 확인할 수 있다.
- 구문
import { BrowserRouter, Routes, Route, Link } from "react-router-dom"
App.js
에 라우팅을 하기 위한 React Router의 주요 컴포넌트를 세팅한다.<BrowserRouter>
컴포넌트는 웹 애플리케이션에서 HTML5의 히스토리 API를 사용해 페이지를 새로고침하지 않고도 주소를 변경할 수 있게 해준다. 또한 <BrowserRouter>
가 상위에 작성되어 있어야 React Router의 컴포넌트들을 사용할 수 있다.function App () {
return (
<BrowserRouter> <-
<div>
<nav>
<ul>
<li>
Home
</li>
<li>
MyPage
</li>
<li>
Dashboard
</li>
</ul>
</nav>
</div>
</BrowserRouter> <-
)
}
index.js
에 <BrowserRouter>
를 넣어서 활용할 수도 있다.import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter> <-
<App />
</BrowserRouter> <-
</React.StrictMode>
);
<Routes>
컴포넌트는 여러 <Route>
컴포넌트를 감싸서 그중 경로가 일치하는 단 하나의 라우터만 렌더링을 시켜주는 역할을 한다. <Routes>
를 사용하지 않으면 매칭되는 모든 요소를 렌더링한다.<Route>
컴포넌트는 path
속성을 지정하여 해당 path
에서 어떤 컴포넌트를 보여줄지 정한다. <Link>
컴포넌트가 정해주는 URL 경로와 일치하는 경우에만 작동된다.<Routes>
와 <Route>
로 주소 경로와 생성한 컴포넌트를 연결해 준다.<Route>
의 path
속성을 이용하여 경로를 작성한다. 이때, 햇갈리지 않게 경로와 컴포넌트 이름을 동일하게 맞춘다.<Route>
태그 안에 element
속성으로 연결하고자 하는 컴포넌트를 넣어준다.function App () {
return (
<BrowserRouter>
<div>
<nav>
<ul>
<li>
Home
</li>
<li>
MyPage
</li>
<li>
Dashboard
</li>
</ul>
</nav>
{/* 주소 경로와 아까 만든 3개의 컴포넌트를 연결해 줍니다. */}
{/* Routes 컴포넌트는 Route 컴포넌트들을 감싸고 있어야 합니다. */}
<Routes>
{/* 경로는 path로 컴포넌트는 element로 연결해 줍니다. */}
<Route path="/" element={<Home />} />
<Route path="/mypage" element={<MyPage />} />
<Route path="/dashboard" element={<Dashboard />} />
</Routes>
</div>
</BrowserRouter>
)
}
path=”*”
이다. 지정되지 않은 주소로 접근할 시에는 이 속성이 설정되어 있는 컴포넌트를 보여주게 된다.ReactDOM으로 렌더를 시키게 되면
<Link>
컴포넌트는<a>
요소로 바뀌는 모습을 볼 수 있다.React Router에서
<a>
요소가 아닌<Link>
를 사용하는 이유는<a>
요소는 페이지를 전환하는 과정에서 페이지를 불러오기 때문에 다시 처음부터 렌더링을 시키기 때문이다. 즉, 새로고침 현상이 일어나게 되는 것이다.
하지만<Link>
컴포넌트는 페이지 전환을 방지하는 기능이 내장되어 있기 때문에 SPA를 구현할 수 있는 것이다.
<Link>
의 to
속성을 활용하여 <Route>
컴포넌트에 설정해 준 path
주소를 연결해 줍니다.function App() {
return (
<BrowserRouter>
<div>
<nav>
<ul>
<li>
{/* Link 컴포넌트를 이용하여 경로를 연결합니다 */}
<Link to="/">Home</Link>
</li>
<li>
<Link to="/mypage">MyPage</Link>
</li>
<li>
<Link to="/dashboard">Dashboard</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/mypage" element={<MyPage />} />
<Route path="/dashboard" element={<Dashboard />} />
</Routes>
</div>
</BrowserRouter>
);
}
function Home() {
return <h1>Home</h1>;
}
function MyPage() {
return <h1>MyPage</h1>;
}
function Dashboard() {
return <h1>Dashboard</h1>;
}
export default App;
여러 페이지에서 동일하게 보여야 하는 네비게이션 메뉴를 만들려고 하면 모든 라우트 컴포넌트마다 거의 똑같은 코드를 작성해야 한다. 리액트 라우터는 이런 번거로움을 줄이고자 Outlet이란 컴포넌트를 제공한다.
Outlet 컴포넌트는 다른 컴포넌트들이 렌더링되는 위치를 지정해 주는 역할을 한다.
Outlet 컴포넌트는 다른 컴포넌트가 렌더링되는 위치를 지정해 주는 용도이므로 Outlet에 보이기 원하는 컴포넌트는 Outlet을 사용하는 컴포넌트(ex: Layout)의 자식 라우터로 구성한다.
// Layout.tsx
import Navigation from './Navigation';
export function Layout() {
return (
<>
<Navigation />
<Outlet />
</>
);
};
// Router.tsx
import {Outlet} from 'react-router-dom'
export default function Router() {
return (
<Routes>
<Route path='/' element={<Layout />}>
<Route path='/board' element={<Board />} />
<Route path='*' element={<Error />} />
</Route>
</Routes>
);
};