라우터와 라우팅
네트워크에서 정보를 주고 받기 위해서는 여러 개의 네트워트 간에 데이터를 전달하는 방법과 경로를 정해주어야 한다. 중간에서 이러한 역할을 수행하는 장치가 '라우터(Router)'이다. 라우터는 여러 개의 네트워크 사이에서 데이터를 적절하게 전달하고 길을 안내하는 역할을 한다.
라우터는 네트워크 간에 데이터 패킷을 전송하는데 사용되며, 각 패킷은 목적지의 IP주소를 가지고 있다. 라우터는 이 목적지의 IP주소를 확인하여 해당 패킷을 어떤 인터페이스로 전송해야하는 지 결정한다 이를 위해 라우터는 라우팅 테이블을 유지하고, 이 테이블에 따라 패킷을 최적의 경로로 안내한다.
이때 라우터가 데이터 패킷을 적절하게 전달하고 길을 안내하는 모든 일련의 과정을 '라우팅(Routing)'이라고 한다. 즉, 라우터는 라우팅을 수행하여 데이터의 목적지로 안전하게 전달하는 것이다.
예를 들어, 사용자가 인터넷을 통해 웹사이트에 접속하려고 할 때, 사용자의 브라우저는 웹 서버에 요청을 보낸다. 이 요청 데이터 패킷은 여러 개의 네트워크를 거쳐 웹 서버로 전달되어야 한다. 라우터는 이 요청 데이터 패킷의 목적지 IP 주소를 확인하여 적절한 경로로 안내하며 웹 서버에서는 요청된 페이지를 찾아 사용자의 브라우저로 반환한다. 이와 같은 과정이 바로 라우팅이다.
MPA와 SPA
Multi-Page Application(MPA)
여러 개의 페이지로 구성된 웹 애플리케이션. 사용자가 웹 애플리케이션 내에서 다른 페이지로 이동할 때마다 서버로부터 해당 페이지에 대한 새로운 HTML을 받아오는 방식으로 동작한다. 이는 각 페이지가 독립적으로 작동하기 때문에 각각의 페이지를 개별적으로 최적화하고 유지보수 할 수 있으며 브라우저가 새로운 페이지를 로드할 때 화면을 전환하는 것으로 사용자가 페이지 간의 전환을 명확하게 인지할 수 있는 장점이 있다. 그러나, 페이지 간의 전환에 따른 렌더링 시간이 필요하고 상태 관리를 위해 브라우저의 자바스크립트 기능을 이용하기 때문에 복잡한 기능을 구현하기 어려울 수 있다. 이러한 한계를 극복하고자 등장한 것이 Single-Page Application(SPA)이다.
Single-Page Application(SPA)
하나의 페이지로 구성된 웹 애플리케이션. 초기에 웹 페이지를 한 번 로드한 후 이후에는 페이지 갱신이나 콘텐츠 로딩 시 페이지를 다시 로드하지 않고 동적으로 콘텐츠를 갱신하는 방식으로 동작한다. 브러우저의 URL을 사용하여 페이지 간의 전환을 관리하는데, 브라우저의 URL이 변경되면 해당 URL에 대응하는 콘텐츠를 동적으로 렌더링한다. 만약 데이터가 필요한 경우 필요한 데이터만 서버에 요청을 하여 비동기적으로 전달받는다. 이렇게 SPA는 필요한 데이터만 요청하고 전달을 받기 때문에, 전체 페이지를 다시 로드하는 것보다 빠른 속도를 제공하며 사용자가 부드러운 경험을 할 수 있도록 도와주다. 또한 필요한 데이터만 가져오기 때문에 효율적인 네트워크도 사용이 가능하다.
대표적인 라이브러리로는 React, 프레임워크로는 Angluer,Vue.js가 있다.
이때 웹 페이지를 브라우저로 로드한 후, 콘텐츠를 동적으로 생성하여 클라이언트측에서 렌더링 하는 동작방식을 Client-Side Rendering(CSR)이라고 한다.
즉, React는 SPA 방식으로 CSR을 통하여 페이지를 렌더링 하는 것이다.
npm i react-router-dom@6
위의 명령어를 리액트 프로젝트 터미널에 입력하여 React Router 라이브러리를 설치해준다.
해당 라이브러리는 React에서 CSR기반의 라우팅을 할 수 있도록 해준다.
BrouserRouter
브라우저의 url과 리액트 앱을 연결하는 컴포넌트로 주로 최상위 컴포넌트인 App.js 컴포넌트를 래핑하여 사용된다. 이렇게 하면 App.js 컴포넌트 내에서 라우팅을 정의하고 브라우저의 URL에 따라 다른 페이지나 뷰를 렌더링할 수 있다.
만약, 해당 프로젝트에서 Home,New, Edit, Diary 총 4개의 페이지가 사용된다면, 먼저 src 폴더 내에 해당 컴포넌트들을 만들어 준 후 App.js에서 import하여 매핑해줄 수 있다.
App.js
import { BrowserRouter, Routes, Route } from 'react-router-dom';
import RouteTest from './components/RouteTest';
// 사용할 페이지 임포트
import Home from './pages/Home';
import New from './pages/New';
import Edit from './pages/Edit';
import Diary from './pages/Diary';
function App() {
return (
<BrowserRouter>
<div className="App">
{/* <Routes> 외부에 있는 요소는 어떤 경로이든 항상 나타는 요소이다.
즉, header와 같이 웹사이트에 전체적으로 필요한 요소라면 Routes 외부에 작성하여 사용하면 된다. */}
<h1>App.js</h1>
{/* url이 바뀌게 되면 어떤 컴포넌트를 렌더링하여 그 컴포넌트가 페이지 역할을 할지 결정하기 위해
Routes 컴포넌트로 래핑 */}
<Routes>
{/* Route: 실질적으로 url 경로와 컴포넌트를 매핑시켜주는 컴포넌트 */}
<Route path="/" element={<Home />} /> {/* path가 index라면 Home 컴포넌트를 렌더하라는 명령*/}
<Route path="/new" element={<New />} /> {/* path가 /new라면 New 컴포넌트를 렌더하라는 명령*/}
<Route path="/Edit" element={<Edit />} /> {/* path가 /Edit라면 Edit 컴포넌트를 렌더하라는 명령*/}
<Route path="/Diary" element={<Diary />} /> {/* path가 /Diary라면 Diary 컴포넌트를 렌더하라는 명령*/}
</Routes>
</div>
</BrowserRouter>
);
}
이제 페이지를 이동시킬 것인데, 기존에 다른 페이지 이동을 할 때는 <a></a>태그를 사용하였다.
하지만, 이는 페이지를 새로 전환하며 이동을 하기 때문에 페이지 이동 시 새로고침과 같은 효과를 통해 이동을 하게 된다. 이는 SPA가 아닌 MPA 방식의 이동이며, SPA의 장점인 빠르고 부드러운 페이지 이동이 불가하다.
그래서 React Router에서는 <a>태그 대신 CSR 방식으로 페이지를 이동하는 별도의 컴포넌트를 사용하여 페이지를 이동을 한다.
RouteTest.js
import { Link } from "react-router-dom";
const RouteTest = () => {
return <div>
<Link to={'/'}>Home</Link> <br />
<Link to={'/Diary'}>Diary</Link> <br />
<Link to={'/New'}>New</Link> <br />
<Link to={'/Edit'}>Edit</Link> <br />
</div>
}
export default RouteTest;
App.js
function App() {
return (
<BrowserRouter>
<div className="App">
// 중략
<RouteTest />
</div>
</BrowserRouter>
);
}
React Router V6 페이지 라우팅 기능
1. Path Variable
URL을 변수에 담아 전달한다. 즉, 경로에 변수를 사용하는 것으로 useParams() Hook을 사용하여 전달받을 수 있다.
이는 전달받아 들어오는 Path Variable을 모아 객체로 가져온다.
* useParams는 React가 제공하는 Hook이 아닌, React Router 라이브러리에서 만든 사용자정의 Hook이다.
// Diary.js
import { useParams } from "react-router-dom";
const Diary = () => {
const {id} = useParams();
return <div>
<h1>Diary</h1>
<p>이곳은 Diary(일기상세페이지)</p>
</div>
}
export default Diary;
// App.js
function App() {
return (
// 중략
// 경로에 :id(변수 이름)를 추가하여 사용
<Route path="/Diary/:id" element={<Diary />} />
)
}
App의 Route에서
로 정의를 해두었기 때문에 URL이 id값이 없는 그냥 /Diary뿐이라면 해당 페이지가 로드되지 않는다. 이럴 땐
와 같이 경로를 추가하면 된다.
2. Qurey String
name과 value를 엮어 데이터를 전송하는 것으로, Path Variable과 다르게 별도의 처리를 하지 않아도 자동으로 매핑이 가능하다.
useSearchParams Hook을 사용하여 쿼리스트링 값에 쉽게 접근하고 조작할 수 있다.
import {useSearchParams } from "react-router-dom";
const Edit = () => {
const [searchParams, setSearchParams] = useSearchParams();
// 쿼리스트링에서 특정 키의 값을 가져오기
const id = searchParams.get("id");
const mode = searchParams.get("mode");
const who = searchParams.get("who")
console.log("id::" , id , " / mode:: ", mode, "/ who::" , who);
return <div>
<h1>Edit</h1>
<p>이곳은 Edit(일기수정페이지)</p>
// 쿼리스트링 값 변경하기
<button onClick={()=>setSearchParams({who: "Hong"})}> 쿼리스트링 바꾸기 </button>
</div>
}
export default Edit;
3. Page Moving
Link 태그를 클릭하지 않아도 의도적으로 페이지를 바꿀 수 있는 것으로 useNavigate Hook을 사용한다. 예를 들어 '장바구니' 버튼을 눌렀을 경우, 회원이 아니라면 로그인페이지로 강제 이동을 하는 경우 등에 사용한다.
import { useNavigate } from "react-router-dom";
const Edit = () => {
// useNavigate: 페이지를 이동시킬 수 있는 함수를 반환(navigate),
// navigate함수를 호출하여 인자로 해당 경로로 이동시킴
const navigate = useNavigate();
return <div>
<h1>Edit</h1>
<p>이곳은 Edit(일기수정페이지)</p>
<button onClick={()=>{navigate("/Home")}}>Home으로 이동</button>
<button onClick={()=>{navigate(-1)}}>뒤로가기</button>
</div>
}
export default Edit;
4. Nested routes
중첩된 라우터로, 하나의 카테고리에 여러 페이지가 동작할 때 사용한다.
<Routes>
<Route path="/event" element={<Event />}>
<Route path="one" element={<EventOne />}/>
<Route path="two" element={<EventTwo />}/>
</Route>
</Routes>
이렇게 event Route 사이에 원하는 페이지를 넣을 수 있다.
이 때, <Outlet>을 사용하여 EventOne, EventTwo 컴포넌트의 위치 또한 지정할 수 있다.
const Event = () => {
return (
<div>
<h1>오늘의 이벤트</h1>
<Outlet></Outlet>
</div>
)
'JS > React' 카테고리의 다른 글
9. Redux를 사용한 상태관리 (0) | 2023.08.27 |
---|---|
8. 라이브러리 사용하여 AJAX 요청하기 (0) | 2023.08.25 |
6. React 프로젝트 만들기 (0) | 2023.05.22 |
5. React? (0) | 2023.05.21 |
4. Node.js (0) | 2023.05.21 |