SPA란?
SPA는 Single-Page-Application의 약자로, 여러 url을 필요한 부분만 렌더링하는 개념을 의미한다.
사용자가 경험하는 모든 웹앱은 서버에 저장되어 있는 웹앱을 인터페이스를 통해 요청하고 응답받는 구조로 되어있다.
이 때, 브라우저는 응답받는 내용대로 웹앱을 정보를 읽고, 이를 화면에 그리는 "렌더링(rendering)"을 진행하게 되는데, 일반적인 웹앱에서는 동일한 정보가 상당히 많이 겹침에도 웹앱 전체를 렌더링한다(MPA). SPA는 이러한 렌더링을 줄이고, 필요한 부분만 렌더링한다는 개념이다.
React-Router-DOM
리액트는 SPA의 구현을 위해 React-Router-DOM 라이브러리를 사용한다.
Router는 네트워크에서 경로를 결정하는 장치나 시스템을 의미하는데, 이 경로를 설정하기 위해 여러 도구들을 모아놓은 라이브러리가 React-Router-DOM이다. (공식문서 : https://reactrouter.com/en/main)
즉, 현재 SPA를 구현하기 위해 가장 많이 사용되는 라이브러리가 React-Router-DOM이라는 라이브러리일 뿐, 언제든지 더 효율적이고 효과적인 개념을 가진 라이브러리가 등장한다면 대체될 수 있다.
React-Router-DOM 시작하기
npm install react-router-dom@6.3.0
일단 React-Router-DOM은 React에서 제공하고 있는 빌트인 개념이 아닌, 라이브러리이기 때문에 npm을 통해 설치해주어야 한다.
특히, React-Router-DOM은 버전에 유의할 필요가 있는데 현재 구글링이나 stackoverflow에서 자주 보이는 예시 및 질의응답들은 대부분 <SWITCH /> 컴포넌트 및 컴포넌트 속성이 아닌 aria에 직접 라우팅하고자 하는 컴포넌트를 넣는 내용이 많다.
이는, v5에서 사용된 개념들이며 v6에서는 여러가지 중요한 변화가 생겼다.
따라서 현재 라우팅이 사용되는 버전이 어떤 버전인지 파악하고 이에 대응하는 코드를 작성할 필요가 있다.
다음은 React-Router-DOM으로 실제 구현한 간단한 예시를 통해 핵심 개념을 살펴보고자 한다.
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
// 외부 컴포넌트를 받아와서 작성하고자 하는 경우, import 구문으로 추가해주면 된다.
// 혹은 routes 폴더를 따로 만들어서 라우팅된 컴포넌트를 가져와 import하는 것도 가능하다.
function Home() {
return <h1>Hello! React-Route</h1>;
}
function About() {
return <h1>라우팅 처리된 About Us</h1>;
}
function Contact() {
return <h1>라우팅 처리된 Contact Us</h1>;
}
// 왜 그런진 모르겠는데, router 내부에서는 주석이 잘 먹히지 않아서 여기에 정리했다.
// 먼저 라우팅하고자 하는 컴포넌트의 최종 렌더링 return을 <BrowserRouter>로 감싸진 내용으로 주어야 한다.
// 이후 nav 영역에서 3개의 버튼으로 routes를 제어하고자 했다.
// 각 버튼의 aria를 <Link to="/경로">컴포넌트로 감싸준다.
// 라우팅하고자 하는 영역들을 Routes 컴포넌트로 감싸준다.
// 이후 Route 컴포넌트에 <Link> 컴포넌트에서 명시한 path=""를 속성으로 주고, element 속성에 라우팅하기 원하는 컴포넌트를 넣는다.
function App() {
return (
<BrowserRouter>
<nav>
<ul>
<button>
<Link to="/">Home</Link>
</button>
<button>
<Link to="/about">About</Link>
</button>
<button>
<Link to="/contact">Contact</Link>
</button>
</ul>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" element={<About />} />
<Route path="/contact" element={<Contact />} />
</Routes>
</BrowserRouter>
);
}
export default App;
<BrowserRouter /> 컴포넌트의 역할
BrowserRouter 컴포넌트는 브라우저의 history 객체를 활용하여 라우팅을 관리한다.
브라우저의 history 객체는 window.history가 랩핑된 객체로 go, back, forward 등의 메서드를 활용하여 브라우저의 세션 히스토리를 관리하고 저장한다.
BrowserRouter가 다른 컴포넌트의 url에 접근할 때, history.pushState() 메서드를 활용하여 주소 표시줄의 url을 바꾸고, Routes 및 Route 정의된 경로 매개변수와 일치하는지 여부를 확인한 뒤, 일치할 경우 원하는 컴포넌트를 렌더링하는 것이다.
결국, Router는 컴포넌트의 상태를 활용하여 브라우저의 상태를 변경시키고 이를 히스토리에 저장하는 가장 기본적인 흐름을 활용한 것이라 볼 수 있다.
라우팅 중첩
라우팅 된 컴포넌트 안에서 하위 라우팅이 필요한 경우, 중첩 라우팅을 사용하게 된다.
이 때는 해당 컴포넌트 자체가 브라우저를 조작하는게 아님으로 브라우저 라우터 컴포넌트가 아닌, Routes 컴포넌트로 감싸줘서 경로를 지정해주게 된다.
이에 대한 예시코드는 다음과 같다.
import { BrowserRouter, Routes, Route, Link } from "react-router-dom";
const Home = () => {
return <h1>Home Page</h1>;
};
const Contact = () => {
return <h1>라우팅처리 된 Contact</h1>;
};
function About() {
return (
<div>
<h1> 중첩 라우팅처리 된 Contact</h1>
<nav>
<ul>
<li>
<Link to="/about/example1">Example01</Link>
</li>
<li>
<Link to="/about/example2">Example2</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/example1" element={<h2>예시1</h2>} />
<Route path="/example2" element={<h2>예시2</h2>} />
</Routes>
</div>
);
}
function App() {
return (
<BrowserRouter>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/contact">Contact</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
</nav>
<Routes>
<Route path="/" element={<Home />} />
<Route path="/contact" element={<Contact />} />
<Route path="/about" element={<About />} />
</Routes>
</BrowserRouter>
);
}
export default App;
'프레임워크&라이브러리 > React.js' 카테고리의 다른 글
React-quill을 활용한 구현 예제 (0) | 2023.04.13 |
---|---|
(Rich-TextEditor) React-quill (0) | 2023.04.12 |
UseRef() (0) | 2023.02.22 |
State Lifting Up(상태 끌어올리기) (0) | 2023.02.21 |
Styled Component (0) | 2023.02.20 |