[React]리액트 라우터 React-Router
[ MPA와 SPA ]
★ MPA
MPA는 Multiple Page Application으로 여러 개의 페이지로 구성된 웹 어플리케이션을 의미하며 SSR(Server Side Rendering)방식으로 렌더링합니다.
MPA는 서버에 새로운 페이지를 요청할 때마다, 신규 페이지를 불러와 페이지 리소스가 다운로드 되어 그에 맞춰 전체 페이지를 다시 렌더링하게 됩니다.
장점 | 단점 |
- 크롤링하기에 적합하다. (SEO 관점에서 유리) - 서버에서 이미 렌더링해 가져오기 때문에 첫 로딩 시간이 짧다. |
- 새로운 페이지를 요청할 때마다 전체 페이지를 다시 렌더링한다. (깜빡임 현상) - UI를 개발할 때 반복적인 코드를 삽입해야 한다. - 한 번 수정할 때는 페이지 전체를 수정해야하기 때문에 유지보수에 어려움이 있다. |
★ SPA
SPA는 Single Page Application으로 페이지가 한 개인 웹 어플리케이션을 의미하며, CSR(Client Side Rendering)방식으로 렌더링합니다.
SPA는 기존 페이지에 컴포넌트화된 서브 페이지나 적절한 데이터만을 넘겨주어, 첫 요청시에 딱 한 페이지만 불러오고 페이지 이동 시 기존 페이지 내부를 수정하는 방식을 사용합니다.
장점 | 단점 |
- 자연스러운 UX - 필요한 리소스만 부분적으로 로딩하여 성능에 좋다. - UI 개발을 빠르게 할 수 있다. - 해당 부분만 수정이 가능하여 유지보수에 좋다. - 컴포넌트별로 코딩을 하기 때문에 코드 재사용성이 좋다. |
- 초기 로딩 시간이 비교적 느리다. - 검색엔진최적화(SEO)가 어렵다. - CSR 방식은 클라이언트측에서 사용자에 대한 정보를 저장하기에 보안 이슈가 있을 수 있다. |
[ React-Router ]
리액트는 SPA 방식으로 구성되어 새로운 페이지를 로드하지 않고 하나의 페이지 안에서 필요한 데이터만을 가져오는 형태를 가집니다.
React-Router는 페이지를 새로 불러오지 않는 상황에서 선택된 데이터를 하나의 페이지에서 렌더링 해주는 라이브러리입니다.
먼저, 다음 명령어를 입력하여 라이브러리를 설치합니다.
// for npm
$ npm install react-router-dom@6
// for yarn
$ yarn add react-router-dom@6
다음으로 src/index.js 로 이동하여 BrowserRouter를 임포트 한 뒤, <App/> 컴퍼넌트를 BrowserRouter 컴퍼넌트로 감싸줍니다.
<BrowserRouter> 는 React-Route를 시작하는 컴포넌트로, <Route> 컴포넌트는 반드시 <BrowserRouter> 내부에 있어야 합니다.
// src/index.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import { BrowserRouter } from 'react-router-dom'; // new!
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<BrowserRouter> // new!
<App />
</BrowserRouter>
</React.StrictMode>
);
reportWebVitals();
[ Route 사용법 ]
<Route>는 path prop을 통해 매칭시킬 경로를 지정하고 element prop을 통해 매치되었을 때 보여줄 컴포넌트를 할당하여, 현재 주소창의 경로와 매치될 경우 해당 컴포넌트를 보여주게 됩니다.
import { Route } from "react-router-dom";
<Route path="경로" element={보여 줄 컴포넌트}></Route>
<예제>
// src/Home.jsx
import React from 'react';
const Home = () => {
return (
<div>
<h1>Home !!!</h1>
</div>
);
};
export default Home;
// src/Login.jsx
import React from 'react';
const Login = () => {
return (
<div>
<h1>Login !!!</h1>
</div>
);
};
export default Login;
// src/App.jsx
import { Routes, Route } from "react-router-dom";
import Home from './Home';
import Login from './Login';
function App() {
return (
<Routes>
<Route path='/' element={<Home />} />
<Route path='/login' element={<Login />} />
</Routes>
);
}
export default App;
[ Link 사용법 ]
<Link>는 html의 <a> 태그와 유사한 기능을 하지만, 페이지 전환을 방지하는 기능이 내장되어 있습니다.
브라우저에서 클릭이 가능한 '내용'을 클릭하게 되면 주소창의 경로는 to props에서 지정한 경로로 갱신됩니다. <도메인경로>/경로
import { Link } from "react-router-dom";
<Link to="경로">내용</Link>
// src/App.jsx
import { Routes, Route, Link } from "react-router-dom";
import Home from './Home';
import Login from './Login';
function App() {
return (
<>
<ul>
<li><Link to='/home'>Home</Link></li>
<li><Link to='/login'>Login</Link></li>
</ul>
<hr />
<Routes>
<Route path='/home' element={<Home />} />
<Route path='/login' element={<Login />} />
</Routes>
</>
);
}
export default App;
[ 라우트 중첩 - Outlet ]
<Route> 로 다른 Route들을 감싸는 것을 라우트의 중첩이라고 합니다.
이때, 하위 Route 들의 내용이 보이도록 하기 위에선 상위 Route의 컴퍼넌트에 <Outlet />을 추가해야합니다.
<Outlet />을 통해서 상위 컴포넌트를 레이아웃화 할 수 있는 것이죠!
<Outlet />이 작성된 위치에 하위 컴포넌트들이 위치하게 됩니다.
// src/Menu.jsx
import React from 'react';
import { Link, Outlet } from 'react-router-dom';
const Menu = () => {
return (
<>
<ul>
<li>
<Link to="/home">Home</Link>
</li>
<li>
<Link to="/login">Login</Link>
</li>
</ul>
<Outlet /> //이 위치에 <Home />과 <Login />이 위치하게 됨
</>
);
};
export default Menu;
// src/App.jsx
import { Routes, Route, Link } from "react-router-dom";
import Home from './Home';
import Login from './Login';
import Menu from './Menu';
function App() {
return (
<>
<Routes>
<Route path="/" element={<Menu />}>
<Route path='/home' element={<Home />} />
<Route path='/login' element={<Login />} />
</Route>
</Routes>
</>
);
}
export default App;