React로 SPA 구현하기
SPA는 하나의 페이지를 가지고 있지만 사실 한 종류의 화면만 사용하지 않는다. 예를 들어 Twittler와 같은 SPA를 만들 때, (1) 메인 트윗 모음 페이지, (2) 알림 페이지, (3) 마이 트윗 페이지 등의 화면이 필요할 수 있다.
Routering의 뜻 / React Router 소개
이 화면에 따라 "주소"도 달라진다. 이렇게 다른 주소에 따라 다른 뷰를 보여주는 과정을 "경로에 따라 변경한다."라는 의미로 라우팅(Routing)이라고 한다. 하지만 React 자체에는 이 기능이 내장되어 있지 않다. 따라서 우리가 직접 주소마다 다른 뷰를 보여줘야 한다. React SPA에서는 라우팅을 위해 React Router라는 라이브러리를 가장 많이 사용한다.
* 정리하자면 React SPA에서는 React Router라는 라이브러리를 사용하여 주소에 따라 다른 뷰를 보여줄 수 있다.
React Router 라이브러리 살펴보기
React Router의 주요 컴포넌트는 크게 3가지로 나눌 수 있다.
- 라우터 역할을 하는 BrowserRouter
- 경로를 매칭해주는 Routes 와 Route
- 경로를 변경하는 역할을 하는 Link
이 컴포넌트들을 사용하기 위해서는 React Router 라이브러리에서 따로 불러와야 한다.
React Router 사용해보기
아래 그림과 같이 간단한 메뉴 페이지를 구현하여 React 웹 애플리케이션의 목업을 만들어보자.
목표
- React Router의 주요 컴포넌트들을 이용해 주소에 따른 3가지 뷰( Home, MyPage, Dashboard )를 제공해야 한다.
- Home 페이지의 주소 "/"
- MyPage 페이지의 주소 "/mypage"
- Dashboard 페이지의 주소 "/dashboard"
1. React Router 라이브러리 설치하기
우선 터미널을 열고 다음 명령어를 실행하여 simpleroute 디렉토리에 create-react-app으로 React 프로젝트 환경을 만들고, 추가적으로 React Router 라이브러리도 설치한다. 실행 후 npm start를 통해 실행 결과가 잘 나오는지 확인해 준다.
라이브러리가 잘 설치되었다면, package.json 파일의 dependencies 항목에 react-router-dom 이라는 라이브러리가 등록된 것을 확인할 수 있다.
이제 App.js 파일로 가서 최상단에 React Router 라이브러리가 제공하는 컴포넌트들을 사용하기 위한 세팅을 진행한다. 컴포넌트를 꺼내오기 위한 import 구문을 작성하면 된다. Import는 필요한 모듈을 불러오는 역할로 비구조화 할당(destructuring assignment)과 비슷하게 이용할 수 있다.
import React from 'react'
import { BrowserRouter, Routes, Route, Link } from "react-router-dom"; // 이 구문을 넣으면 됨
2. 라우트 준비하기 (경로에 따라 변경될 각각의 페이지)
App.js 하단에 페이지를 표시하는 컴포넌트 Home, MyPage, Dashboard를 만들어준다.
// Home 컴포넌트
function Home() {
return <h1>Home</h1>;
}
// MyPage 컴포넌트
function MyPage() {
return <h1>MyPage</h1>;
}
// Dashboard 컴포넌트
function Dashboard() {
return <h1>Dashboard</h1>;
}
3. 메뉴 만들기
<ul> 요소와 <li> 요소를 이용하여 각 컴포넌트로 이동할 메뉴를 제작한다.
function App () {
return (
<div>
<nav>
<ul>
<li>
Home
</li>
<li>
MyPage
</li>
<li>
Dashboard
</li>
</ul>
</nav>
</div>
)
}
export default App;
4. 주소에 따라 페이지 뷰 다르게 만들기
- 이제 위에서 만든 3개의 컴포넌트를 "주소"에 따라 다르게 만든다.
- Home 페이지의 주소 "/"
- MyPage 페이지의 주소 "/mypage"
- Dashboard 페이지의 주소 "/dashboard"
- App.js 에 라우팅을 하기 위한 React Router의 주요 컴포넌트를 세팅한다. 이 컴포넌트를 이용해서 원하는 "주소에 따른 다른 페이지"를 구현할 수 있다.
5. BrowserRouter 컴포넌트
<BrowserRouter> 컴포넌트는 웹 애플리케이션에서 HTML5의 History API를 사용해 페이지를 새로고침하지 않고도 주소를 변경할 수 있게 해준다. 또한 <BrowserRouter> 가 상위에 작성되어 있어야 React Router의 컴포넌트들을 사용할 수 있다. 다시 말해 <BrowserRouter>는 React Router DOM이 사용되는 부분의 최상위 컴포넌트로 위치해야 한다.
function App () {
return (
<BrowserRouter> 🟣 여기에 위치!!!
<div>
<nav>
<ul>
<li>
Home
</li>
<li>
MyPage
</li>
<li>
Dashboard
</li>
</ul>
</nav>
</div>
</BrowserRouter> 🟣 여기에 위치!!!
)
}
export default App;
* 아래와 같이 ReactDOM의 렌더 단계인 index.js 에 <BrowserRouter>를 넣을 수도 있다.
index.js (React Version 18 기준)
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>
);
index.js (React Version 17 기준)
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter } from 'react-router-dom';
ReactDOM.render(<BrowserRouter><App/></BrowserRouter>, document.querySelector('#root'));
6. Routes, Route
경로를 매칭해주는 역할을 하는 컴포넌트이다. (React Router v6 부터는 Switch가 아닌 Routes 컴포넌트를 사용한다.)
- <Routes> 컴포넌트는 여러 <Route> 컴포넌트를 감싸서 그중 경로가 일치하는 단 하나의 라우터만 렌더링을 시켜주는 역할을 한다. <Routes> 를 사용하지 않으면 매칭되는 모든 요소를 렌더링한다.
- <Route> 컴포넌트는 path 속성을 지정하여 해당 path 에서 어떤 컴포넌트를 보여줄지 정한다. 아래에 나올 <Link> 컴포넌트가 정해주는 URL 경로와 일치하는 경우에만 작동된다.
하는 방법
- <Routes> 와 <Route> 로 주소 경로와 아까 만든 3개의 컴포넌트를 연결해 준다.
- <Route>의 path 속성을 이용하여 경로를 작성한다. 경로와 컴포넌트 이름이 동일해야 헷갈리지 않는다.
- <Route> 태그 안에 element 속성으로 연결하고자 하는 컴포넌트를 넣어준다.
만약 사용자가 지정된 주소인 “/’, “/mypage”, “/dashboard” 이외의 주소로 접근하게 되면 의도한 화면이 보이지 않을 수 있다. 정의하지 않은 경로를 핸들링할 때 사용할 수 있는 속성이 path=”*” 이다.Route의 경로를 path='*'로 설정하면 사용자가 개발자가 지정되지 않은 주소로 접근할 시에는 이 속성이 설정되어 있는 컴포넌트를 보여주게 된다.
예를 들어, 직접 구성한 404 페이지(존재하지 않는 페이지) 등으로 연결해줄 수 있다.
7. Link
경로를 연결해 주는 역할을 하는 컴포넌트이다. Link 컴포넌트를 클릭하면 Route의 path와 일치하는 페이지로 이동한다. 페이지 전환을 통해 페이지를 새로 불러오지 않고 애플리케이션을 그대로 유지하여 HTML5 History API를 이용해 페이지의 주소만 변경해 준다.
* ReactDOM으로 렌더를 시키게 되면 <Link> 컴포넌트는 <a> 요소로 바뀌는 모습을 볼 수 있다.
[React Router에서 <a> 요소가 아닌 <Link>를 사용하는 이유 ]
- <a> 요소는 페이지를 전환하는 과정에서 페이지를 불러오기 때문에 다시 처음부터 렌더링을 시킨다. (새로고침 현상)
- <Link> 컴포넌트는 페이지 전환을 방지하는 기능이 내장되어 있기 때문에 SPA를 구현할 수 있다.
하는 방법
- <Link> 의 to 속성을 활용하여 <Route> 컴포넌트에 설정해 준 path 주소를 연결해 준다.
function App() {
return (
<BrowserRouter>
<div>
<nav>
<ul>
<li>
<Link to="/">Home</Link> 🟣 {/* 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;
8. 완성
npm run start 를 통해 실제로 Create React App 프로젝트 환경에서 React Router를 통해 SPA가 구현되었는지 확인해본다.
useNavigate
[Link와 다른 점]
useNavigate 는 Link와는 달리 함수 호출을 통해 특정 조건에 따라 페이지를 이동할 수 있다.
import { useNavigate } from "react-router-dom";
function MypageForm() {
let navigate = useNavigate();
function handleClick() {
if(로그인 한 상태) {
navigate('/mypage');
} else {
navigate('/login');
}
}
return <button onClick={handleClick}>마이페이지</button>;
}
useNavigate는 특정 행동을 했을 때 해당 주소로 이동시켜주는 역할을 한다. 따라서 로그인이 되어 있을 경우 버튼을 누르면 navigate('/mypage')가 실행되어 mypage로 이동한다.
'FE > React' 카테고리의 다른 글
[React] React에서 데이터를 다루는 Props & State (0) | 2023.03.24 |
---|---|
[React] React로 Router 기능을 담은 SPA 구현해보기 + useNavigate (0) | 2023.03.23 |
[React] React SPA (0) | 2023.03.23 |
[React] React Twitter Intro - 컴포넌트 기반 개발하기 (0) | 2023.03.23 |
[React] 컴포넌트 기반 개발의 중요성 (0) | 2023.03.22 |