2. React Router

hyeongjundev·2022년 1월 23일
0

backswim

목록 보기
2/8

React Router는 웹 애플리케이션에서 URL변경과 history을 저장하기 쉽게 해주는 모듈 입니다.

여기서, 궁금한 점이 2가지가 있습니다.

Q1. React Router는 URL 변경과 history 저장을 쉽게하는 것 외 다른 목적은 없을까?
Q2. SPA를 지원하는 React에서 URL을 변경하는 것은 성능에 영향을 끼치지 않을까?(불필요한 렌더링이 되지 않을까?)

먼저, 질문에 대한 대답은

A1. 저장을 쉽게하는 것이 목적입니다.
A2. 성능에 악영향을 끼치지 않습니다.

아래 React Router의 소개글을 보며 그 이유를 알아봅시다.

History and Locations

브라우저는 유저가 navigate 할 수 있는 history stack을 관리합니다. 여기서 navigate는 뒤로가기 또는 앞으로 가기 버튼으로 이동하는 것을 이야기 합니다.

예제를 보는 것이 이해를 더 빠르게 도울 수 있을 것 입니다. 아래는 history stack이 쌓이는 과정입니다.

먼저, User의 행동입니다.
1. 링크 /dashboard 클릭
2. 링크 /accounts 클릭
3. 링크 /customers/123 클릭
4. 뒤로가기 버튼 클릭
5. 링크 /dashboard 클릭

아래는 유저의 행동에 따라 변한 history stack 입니다. 볼드체는 현재 URL 입니다.
1. /dashboard
2. /dashboard, /accounts
3. /dashboard, /accounts, /customers/123
4. /dashboard, /accounts, /customers/123
5. /dashboard, /accounts, /dashboard

전형적인 웹사이트(JavaScript가 없는 HTML)는 유저가 link를 클릭하거나, form을 제출하거나, 뒤로가기, 앞으로 가기 버튼을 클릭하면 URL이 변경되어 서버에게 매번 request를 요청합니다. 위의 예제에서는 step3->step4에 해당합니다.

그럼, 어떻게 하면 URL 변경 시 필요한 동작만 할 수 있을까요?

History Object

먼저 React Router를 사용하지 않는 방법입니다.

<a
  href="/contact"
  onClick={event => {
    // URL 변경의 기본 동작을 취소
    event.preventDefault();
    // 브라우저의 history stack에 entry를 넣고 URL을 변경
    window.history.pushState({}, undefined, "/contact");
  }}
/>

위의 코드는 URL을 변경하지만 브라우저의 기본 동작인 렌더링이 일어나지 않습니다. 하지만 개발자들은 URL이 변경되었을 때 어떤 동작을 실행 시키고 싶을 것 입니다. 아래는 URL 변경을 listen하는 handler를 등록하는 예 입니다.

window.addEventListener("popstate", () => {
  // 동작
});

브라우저는 URL 변경에 따른 handler를 등록할 수 있습니다. 하지만 위 이벤트는 뒤로가기, 앞으로 가기 버튼을 눌렀을 때만 fire 됩니다. window.history.pushState 또는 window.history.replaceState에는 반응하지 않는 불편함이 있습니다.

React Router는 이런 불편함을 해소할 수 있습니다.

let history = createBrowserHistory();
history.listen((location, action) => {
  // 새로운 location이 추가될 때 마다 호출
  // action은 POP 또는 PUSH, REPLACE 입니다
});

React Router를 사용하여 history 관리를 쉽게할 수 있으며, 불필요한 렌더링이 일어나지 않아 성능에 큰 영향을 끼치지 않는 것을 보실 수 있습니다.

Locations

브라우저는 history 객체 외 window.location 객체를 가지고 있습니다. 해당 객체는 URL의 정보와 메소드를 가지고 있습니다.

window.location.pathname; // /getting-started/concepts/
window.location.hash; // #location
window.location.reload(); // 서버를 강제 로드합니다.
// 그 외 ...

React Router는 window.location 보다 사용성이 높은 객체를 사용합니다.

{
  pathname: "/bbq/pig-pickins",
  search: "?campaign=instagram",
  hash: "#menu",
  state: null,
  key: "aefz24ie"
}

위 객체는 아래와 같이 이용할 수 있습니다.

let location = {
  pathname: "/bbq/pig-pickins",
  search: "?campaign=instagram&popular=true",
  hash: "",
  state: null,
  key: "aefz24ie"
};

// location.search는 URLSearchParams를 이용하여 쉽게 사용할 수 있습니다.
let params = new URLSearchParams(location.search);
params.get("campaign"); // "instagram"
params.get("popular"); // "true"
params.toString(); // "campaign=instagram&popular=true",

React Router를 이용하여 사용성이 높아지는 것을 보았습니다.

이제 React Router를 프로젝트에 적용을 해보겠습니다.

React Router 적용

아래는 프로젝트에 적용한 React Router 코드 블럭이며, 간략한 설명을 덧붙였습니다. 자세한 설명은 tutorial 을 참조하시면 됩니다.

<BrowserRouter>
  <Routes>
    <Route path="/" element={<Home></Home>}></Route>
    <Route path="/signIn" element={<SignIn></SignIn>}></Route>
    <Route path="/signUp" element={<SignUp></SignUp>}></Route>
    <Route path="/myPage" element={<MyPage></MyPage>}></Route>
    <Route path="*" element={<NotFound></NotFound>}></Route>
  </Routes>
</BrowserRouter>
  • <BrowserRouter>는 history를 생성하고 초기 location을 stack에 넣습니다.
  • <Routes><Route>를 위한 부모 태그이며 route config를 만들고 route를 location가 match 시킵니다.
  • 부모 route는 <Outlet/>을 render 해야 합니다.
  • outlet은 route matches의 다음 match를 render 합니다.
  • link는 navigate()를 호출합니다.
  • history 변경이 일어나고 <BrowserRouter>에 변경을 알립니다.
  • <BrowserRouter>이 다시 렌더링되고, 두번쨰 단계를 다시 시작합니다.

결론

React Router는 history 관리와 navigation의 사용성을 높여주는 모듈이며 애플리케이션의 확작성을 높여줍니다.

참고자료

https://reactrouter.com/docs/en/v6/getting-started/concepts

0개의 댓글