티스토리 뷰

보통 React를 배운다고 하면 react-router-dom이라는 라이브러리를 가장 먼저 알게 되는 것 같은데요. 오늘은 이 쓸 줄만 알았던 react-router-dom의 동작원리에 대해서도 알아보고! v6가 되면서 변경된 사항까지도 알아봅시다 :)
React Router
React에서 Router라는 건, 웹 페이지를 다시 로드하지 않고 (즉, 새로고침 X) 사용자 요청에 따라 애플리케이션의 다른 부분 또는 다른 페이지로 이동하는 프로세스입니다.
그건 그렇다치고... React Router가 필요한 이유는?
여러 페이지를 넘나들 때 웹 페이지를 다시 로드하지 않으면서 이동하기 위해서인데요.
React에 router 없이도 페이지 이동은 가능합니다! 다만, 이전 페이지로 돌아온다고 했을 때, 그 이전 페이지는 이미 로드가 되었음에도 페이지를 새로 처음부터 다시 불러올 것입니다.
❓ 웹 페이지를 다시 로드하지 않으면서 이동하는 것이 중요한 이유
- 더 나은 사용자 경험
- 페이지를 다시 로드하지 않고 이동함으로써 부드러운 전환과 빠른 페이지 로딩 속도 경험
- 페이지를 다시 로드할 경우 처음부터 모든 리소스를 불러와야 하므로 상대적으로 시간이 오래 걸릴 수 밖에 없음
- 상태 유지
- 페이지를 다시 로드하지 않는다면, 현재 페이지의 상태를 유지할 수 있다.
- 예를 들어, 양식을 작성 중이거나 스크롤 위치를 변경한 경우에도 이동 후에도 이전 상태를 유지하는 것이 가능
- 성능 향상
- React는 가상 DOM을 사용하여 페이지를 업데이트하는데
- 페이지 전체를 다시 렌더링 하지 않고도 변경된 부분만 업데이트하면 된다.
- 페이지를 다시 로드하지 않으면, 전체 페이지를 다시 렌더링할 필요가 없으므로 자원과 시간을 절약
Route & Router & Routing
- 라우트(route) : URL 경로와 해당 경로에 대응하는 컴포넌트 사이의 매핑을 정의
- 라우터(router) : URL의 경로를 기반으로 어떤 컴포넌트를 보여줄지 결정
- 라우팅(routing) : 다른 페이지로 이동할 때 해당 경로에 맞게 이동
Routing 작동 방식 (매커니즘)
React는 SPA(Single Page Application)로, 경로에 따라 다른 뷰를 보여줄 수 있는 개념을 활용합니다.

뷰에 따라 path를 매핑하고 그 path가 들어왔을 때 해당하는 컴포넌트를 보여주도록 합니다.
- 라우팅 시스템 설정
- React Router는 최상위 컴포넌트인 `<BrowserRouter>` 를 사용하여 라우팅 시스템을 설정
- `<BrowserRouter>`는 브라우저 HTML5 History API를 사용하여 URL을 관리 → 라우팅을 처리
- URL 경로와 컴포넌트 간의 매핑
- `<BrowserRouter>` 컴포넌트 안에는 여러 개의 `<Route>` 컴포넌트가 포함
- `<Route>` 컴포넌트들은 URL 경로와 컴포넌트 간의 매핑을 설정하는 역할
- `<Route path="/about" component={About} />`
💡 React Router는 브라우저의 현재 URL을 확인
→ <Route> 컴포넌트의 path prop과 URL 경로를 비교
→ 일치하는 컴포넌트를 렌더링
react-router-dom v6 변경사항들
1. Switch 대신 Routes
- Switch의 네이밍이 Routes로 변경
- exact 옵션 삭제 → 기본적으로 정확히 일치하도록 변경
- Switch는 경로가 적합한 처음 한 컴포넌트를 찾아주었는데, 여기서 발생하는 적합한 url의 순서를 뒤로 지정해주어 발생하는 버그를 방지
- exact 속성을 주면 자신의 path에 정확하게 위치해야만 자신의 컴포넌트가 렌더링되었는데
- 만약 옵션을 주지 않으면 해당 path가 포함되기만 해도 그 컴포넌트로 매핑이 되었었다.
- 즉, path=”/”에 exact를 설정해주지 않으면 / 이고, /home이든 /home/my 이든 전부 /로 매핑
// v5
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
</Switch>
// v6
<Routes>
<Route path="/" element={<Home />} />
<Route path="/about" component={About} />
</Routes>
2. 중첩 라우팅(nested routing)
- 계층적 방식으로 경로를 정의하는 방법
// '/service' 하위 경로들
/service/development
/service/consulting
/service/outsourcing
/service/:category
// ==> /service 경로에 중첩
만약 하위 경로들에 대해 중첩되는 부분의 컴포넌트가 있다고 하면, (ex. 마이페이지, 헤더 푸터, ..) 전체 페이지를 렌더링할 필요가 없고, 해당 URL 변경에 종속되 페이지 내의 영역만 렌더링하면 되겠죠?

// 방법1
<Route path="/messages" element={<Messages />}>
<Route path=":id" element={<Chats />} />
</Route>
// 방법2
import { Outlet } from "react-router-dom";
function Messages() {
return (
<>
<Conversations />
<Outlet />
</>
);
}
하위 경로 요소에 렌더링될 때 중첩된 UI가 표시됩니다. 상위 경로가 정확히 일치하면 하위 경로를 중첩하게 부분적으로 추가 렌더링하게 되는 것이죠!
3. Dynamic Segments
- 경로 매개변수와 쿼리 문자열을 사용하여 동적인 라우팅을 처리 가능
- 아래와 같이 경로 매개변수는 콜론( : )으로 시작하는 이름으로 정의 가능
- 이후에 경로에 접근했을 때 순차적으로 경로 패턴을 매핑할 라우트 검색
- ⇒ 그래서 경로 매개변수와 동일한 path depth 자리에 정적으로 매핑해주고 싶다면
- ⇒ 경로 매개변수의 라우트보다 상단에 선언해주어야 한다
<Route path="/users/:id" element={<UserDetail />} />
위와 같이 정의된 라우트는 `useParams` 훅을 사용하여 추출이 가능합니다.
// `/users/12` 으로 접근한다면
const { id } = useParams();
console.log(id); // 12
4. useHistory 대신 useNavigate
// v5
let history = useHistory();
function handleClick() {
history.push("/home");
}
// v6
let navigate = useNavigate();
function handleClick() {
navigate("/home");
}
- useHistory → useNavigate로 변경된 주요한 이유
- React Suspense와 더 나은 호환성을 제공하기 위함
- 이미 클릭한 링크가 로드되는 동안 다른 경로에 대한 링크를 클릭한 경우
- 보다 원활한 환경을 제공 가능
- 내부 보류 중인 탐색 상태를 인식하고 기록 스택에 푸시하는 대신 교체를 수행
이전에 클릭된 링크가 아직 로딩 중일 때 React Suspense는 이러한 상황을 처리하기 위해 fallback 컴포넌트를 대체합니다. useNavigate를 사용하면 로딩 중인 페이지에서 라우트 전환이 일어나면 이전 로딩 중인 라우터 전환이 아직 완료되지 않은 상태를 인지하여 이전 전환을 취소 (Suspense 취소) 하고 새로운 전환을 수행합니다.
결론적으로, useNavigate는 React Suspense와의 더 나은 호환성을 제공하여 사용자 경험을 향상 그리고 중단 가능한 라우트 전환 관리를 가능하게 해준다는 점입니다.
'프론트엔드 > React' 카테고리의 다른 글
| [React] Hook는 맨날 쓰는데 '최적화'를 좀 해보자 (0) | 2023.06.21 |
|---|---|
| [React] React Testing Library과 관련된 일반적인 실수 (0) | 2023.06.15 |
| [React] Automatic Batching - 일괄 처리 (0) | 2023.06.14 |
| [React] Lazy loading과 Code splitting - 적당히 적당히 가져오자 (0) | 2023.06.13 |
| [React] Virtual DOM과 ✨React 렌더링 동작 원리✨ with Fiber (2) | 2023.06.12 |
- Total
- Today
- Yesterday
- 프론트엔드 공부
- testing
- 자바스크립트
- next.js
- 리액트 훅
- styled-components
- 프론트엔드
- Python
- TypeScript
- 파이썬
- 딥러닝
- 프로젝트 회고
- 리액트
- 데이터분석
- 인프런
- 타입스크립트
- 머신러닝
- 스타일 컴포넌트 styled-components
- JSP
- 자바
- jest
- CSS
- HTML
- react-query
- 프론트엔드 기초
- 디프만
- frontend
- react
- rtl
- 자바스크립트 기초
| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | ||||
| 4 | 5 | 6 | 7 | 8 | 9 | 10 |
| 11 | 12 | 13 | 14 | 15 | 16 | 17 |
| 18 | 19 | 20 | 21 | 22 | 23 | 24 |
| 25 | 26 | 27 | 28 | 29 | 30 | 31 |