[React Router] Router를 이용해 페이지 이동을 할 수 있는 이유 (History)

·2024년 5월 28일

Study Note ✍🏻

목록 보기
40/60

클라이언트 사이드 렌더링을 하는 SPA(Single Page Application)의 특징을 가지는 React에서 다른 URL마다 다른 컴포넌트 뷰를 보여주려면 React-Router 라이브러리가 필요하다. 또한 클릭이벤트가 발생할 때 페이지를 새로고침 없이 이동하기 위해 history를 활용할 수 있다.

History API

브라우저가 관리하는 세션 히스토리(session history), 페이지 방문 이력을 제어하기 위한 웹 표준 API. 웹 애플리케이션이 브라우저의 세션 기록 스택을 조작하고 탐색 기록을 관리할 수 있게 해준다. 여기서 세션은 브라우저마다 살짝 다를 수 있지만 보통 사용자가 새 창이나 탭을 열 때 생성되고 해당 창이나 탭을 닫을 때 소멸한다. 이를 통해 페이지 리로드 없이 URL을 변경하고, 사용자가 브라우저의 뒤로 가기 및 앞으로 가기 버튼을 사용할 수 있게 한다.

자바스크립트에서 History API는 기본적으로 history 전역 객체를 통해서 사용해 볼 수 있으며 window나 document 전역 객체를 통해서도 접근할 수 있다.

history.length; // 1
window.history.length; // 1
document.history.length; // 1

현재 세션에서 얼마나 많은 페이지를 방문했는지는 History API에서 제공하는 length 프로퍼티에 접근하면 된다. history.back(), history.forward(), history.go() 메서드는 SPA에서 잘 사용되지 않는다. 메서드를 호출하면 브라우저는 해당 페이지를 reload하게 되지만, SPA에서는 일반적으로 URL이 바뀌더라도 전체 페이지를 다시 로딩하지 않기 때문이다.

브라우저의 현재 URL 조작할 수 있는 pushState()replaceState() 메서드는 브라우저 주소 표시줄의 URL만 갱신되고 실제로 해당 페이지가 다시 불러오지는 않는다. 이러한 특징 때문에 자바스크립트로 해당 URL에 맞게 페이지를 부분 업데이트할 수 있다.

pushState

세션 기록 스택에 새로운 상태를 추가합니다.

replaceState

현재 세션 기록의 상태를 새로운 상태로 대체합니다.

사용자가 브라우저에서 뒤로 가기나 앞으로 가기를 하면 back()이나 forward() 메서드를 호출한 것처럼 브라우저가 페이지를 다시 불러오게 된다. 이렇게 될 경우 SPA에서 문제가 발생할 수 있다. “뒤로 가기”나 “앞으로 가기” 버튼은 통제할 수 있는 페이지 상 밖에 위치하여 클릭 이벤트를 감지할 수는 없다. 이를 해결해주는 방법이 PopStateEvent이다. 사용자가 브라우저에서 뒤로 가기나 앞으로 가기를 할 때 window 전역 객체에서 발생한다. 그러므로 자바스크립트로 이벤트 핸들러를 걸어서, 해당 URL에 부합하는 내용을 클라이언트에서 렌더링할 수 있다.

window.addEventListener("popstate", (event) => {
  // 이벤트에 들어 있는 상태 객체를 읽어서 클라이언트 단 라우팅 처리
});

History

React Router의 History는 브라우저의 History API를 기반으로 하여 SPA 내에서 라우팅을 관리하는데 더 높은 수준의 추상화를 제공한다. React Router는 자체적으로 History 객체를 사용하여 브라우저의 탐색을 관리하며, 이 History 객체는 브라우저의 History API를 내부적으로 사용한다.

push(path, state): 새로운 경로로 이동하고 새로운 항목을 세션 기록 스택에 추가
replace(path, state): 현재 항목을 새로운 경로로 대체
go(n): 현재 위치에서 n만큼 이동
goBack(): 이전 페이지로 이동
goForward(): 다음 페이지로 이동

React Router에서 경로를 변경할 때는 push 메서드가 사용된다. 새로운 경로가 현재 경로를 대체하면서 이전 페이지를 브라우저 히스토리 스택에 추가하게 된다. 즉, 사용자가 뒤로가기를 누르면 이전 페이지로 이동할 수 있다.
replace는 보통 이전 페이지에 접근하는 것이 어색한 상황에 사용된다. 주로 사용되는 예로는 로그인 완료 후 뒤로가기를 눌렀을 때 로그인 페이지로 다시 접근이 가능한 것은 어색한 상황이다. 이를 방지하기 위해 replace를 사용해 새로운 경로로 대체해줄 수 있다.

실제 프로젝트에서는 다음과 같은 이슈가 있었다.
React Router를 이용하여 비회원 접근 제어를 진행해주었다. 이때, 회원만 접근 가능한 페이지를 비회원이 접근했을 때 로그인 페이지로 강제 이동을 시켜주게 되었는데, 이 경우 뒤로가기 버튼이 작동을 하지 않았다.

그 이유는 History stack에 메인페이지 -> 회원 접근 페이지 -> 로그인이 추가되어 뒤로가기를 눌러도 다시 회원 접근 페이지로 이동하기 때문에 로그인 페이지로 다시 돌아오지만, 사용자에게는 변함이 없는 것으로 보이게 된다. 이를 해결해주기 위해 로그인으로 이동시킬 때 Navigate에 replace 속성을 추가해주어 해결하게 되었다.


History는 사실 Router를 구현하면서 굳이 신경쓰지 않았던 부분이었다. Router를 사용하는 이유는 단순히 라우팅을 구현하기 위함이라고 생각했고, 페이지 이동 잘 되면 그만~ 이라고 생각했는데 사용자 테스트에서 해당 오류를 발견해준 사람이 있어서 이 부분에 대한 오류 해결 방법을 찾아보다가 History에 대해 알게 되었다. 당시에는 아~ 이런 게 있구나 하고 넘어갔지만, 자세하게 알고싶어서 프로젝트 후 찾아보게 되었다. 프론트엔드는 참 할 게 정말 많다는 걸 느꼈다. 사용자 경험도 생각해야 하고, 기능도 잘 굴러가야 하고.. 그 와중에 신경 써줘야 할 건 정말 한 두가지가 아니다. 뒤로가기 버튼까지 신경써줘야 한다는 것에 정말... 프론트엔드는 다재다능해야 하구나를 배운 것 같다. 나름 그런 구현들이 재미있지만, 아직도 내가 모르는 것들도 구현해야 하는 게 정말 많겠지???????? 프론트엔드 공부는 진짜... 힘들다는 걸 또 한 번 배우고 간다.

참고 자료

Project_Cheerleader — (2) React Route dom history를 사용한 페이지 이동
자바스크립트의 History API와 클라이언트 단 라우팅

profile
Frontend🍓

0개의 댓글