한 번에 끝내는 자바스크립트
Search

5. SPA와 라우팅

지난 시간에는 MPA와 SPA에 대해 배우면서, CSR과 SSR에 대한 개념을 배워보았습니다. 이번에는 SPA에 대해, 그리고 라우팅이라는 개념에 대해 더 자세하게 살펴보도록 하겠습니다.

SPA

SPA는 웹 애플리케이션 또는 웹사이트의 현대적인 구현 방식 중 하나로, 사용자에게 빠르고 부드러운 사용 경험을 제공합니다. SPA의 핵심은 사용자와의 상호작용 중에 웹 페이지를 새로 불러오지 않고, 필요한 데이터만 서버로부터 동적으로 불러와 페이지를 업데이트한다는 것인데요, 이러한 방식은 현대적인 웹 애플리케이션의 개발에 있어서 널리 채택되는 방식입니다. SPA 방식을 체택한 가장 대표적이고 인기있는 프레임워크 및 라이브러리로는 React, Angular, Vue가 있습니다.

라우팅

그럼 이번에는 ‘라우팅’ 이라는 개념에 대해 살펴보겠습니다. 웹 페이지 라우팅이란, 웹 사이트 내에서 웹 주소(URL)을 특정 페이지에 연결하는 과정이라고 할 수 있습니다. 이를 통해 사용자가 브라우저에서 URL을 입력하거나, 어떠한 링크를 클릭할 때, 애플리케이션이 해당 요청에 맞는 적절한 페이지를 반환할 수 있습니다. 즉, 다음과 같이 사용자가 특정 웹 주소(URL)의 뒤에 / 를 붙여 웹 페이지에 접속하면, 브라우저는 해당 주소에 맞는 페이지를 반환할 수 있습니다.
SPA에서 라우팅은 사용자가 다양한 페이지나 뷰로 이동할 수 있게 하면서도 실제로 전체 페이지를 새로 로드하지 않고, 변화가 필요한 요소만을 변경하는 기술입니다. SPA에서 라우팅은 페이지 전환 시 서버에서 HTML 파일을 새로 불러오는 대신, JavaScript를 사용하여 클라이언트 측에서 동적으로 필요한 데이터를 불러오고 콘텐츠를 렌더링합니다.
우리가 개발했던, 웹 페이지를 잠시 살펴보겠습니다. 지금은 웹 페이지에서 펭귄, 코알라, 판다 버튼을 눌렀을 때 웹 페이지의 주소에는 아무런 변화가 없는 것을 볼 수 있습니다. SPA는 단일 HTML 페이지로 구성되어 있으므로, 이렇게 주소에 변경없이 페이지를 자연스럽게 이동할 수 있지만, SPA에서는 웹 페이지를 조금 더 직관적으로 사용할 수 있고, 뒤로 가기, 앞으로 가기와 같은 내비게이션 기능을 지원해 사용자가 여러 페이지를 탐색하는 것처럼 느끼게하기 위해 클라이언트 측에서 ‘라우팅’을 처리하는 것이 일반적입니다.
실제로도 앞서 언급했던, SPA 방식의 인기있는 프론트엔드 라이브러리, 프레임워크인 React.js, Angular, Vue.js에서도 자체적으로 제공되는 라우팅 기능을 사용해 해당 기능들을 개발합니다. 하지만 바닐라 자바스크립트로 개발한 SPA에서는 자체적으로 제공되는 라우팅 기능이 없기 때문에, 브라우저에서 제공하는 History api를 사용해 라우팅을 처리합니다.

History API

History API는 브라우저가 관리하는 세션 히스토리 즉, 사용자가 웹 브라우저를 사용해 방문한 페이지들의 목록을 제어할 수 있도록 HTML5가 제공하는 웹 API 입니다. 크롬 브라우저에서 웹 페이지를 열어보면, 앞으로 가기 버튼과 뒤로 가기 버튼이 있는데요, 현재는 새로운 창을 열었기 때문에, 방문한 페이지 내역이 없는, 세션 히스토리가 비어있는 상태이므로 앞으로 가기 버튼과 뒤로 가기 버튼이 활성화되지 않은 것을 볼 수 있습니다. 이제 다른 페이지로 이동을 해보면, 앞으로 가기 버튼과 뒤로 가기 버튼이 활성화되고, 세션 히스토리를 통해 이 두 버튼들이 동작하게 됩니다. History API를 사용하면 이러한 기능을 사용할 수 있습니다.
우리가 개발했던 웹 사이트에 페이지 라우팅을 적용하기 위해, 먼저 간단한 예제 코드로 History API를 사용하는 방법에 대해 배워보겠습니다. 자바스크립트에서 History API는 ‘history’라는 객체를 통해 사용할 수 있는데요, 이를 사용해보기 위해, 먼저 빈 폴더를 생성한 다음 VSCode에서 해당 폴더를 열어주도록 하겠습니다.
먼저 index.html에는 다음과 같은 코드를 작성해주도록 하겠습니다.
코드를 불러오는 중 입니다 ...
 
코드를 다음과 같이 작성하고, src 폴더에 index.js 파일을 생성해주도록 하겠습니다. index.js 파일에는 먼저, 버튼을 누르면 알맞은 페이지를 이동할 수 있도록 changePage라는 함수를 만들어주겠습니다.
changePage 함수는 매개변수로 이동할 page를 받고, id가 content인 요소를 가져와, 해당 요소에 ‘현재 보고 있는 페이지는 ${page} 입니다.’ 를 텍스트로 입력해주도록 하겠습니다.
코드를 불러오는 중 입니다 ...
 
그리고, addEventListener를 사용해서 버튼 요소들을 클릭할 때 changePage 함수가 실행될 수 있도록 코드를 작성해주겠습니다.
코드를 불러오는 중 입니다 ...
 
다음과 같이 코드를 작성했다면, 이제 history api를 사용해보겠습니다. 페이지가 이동될 때마다 history 객체를 사용해서 이동한 페이지의 정보를 저장해주도록 하겠습니다.
history 객체의 pushState라는 메서드를 사용하면, 세션 히스토리에 현재의 상태를 추가할 수 있습니다. pushState 메서드는 순서대로 state, title, url을 전달합니다. state는 페이지 상태 객체이고, title은 브라우저의 타이틀, 그리고 url은 해당 페이지의 주소를 나타냅니다.
우리는 state에 객체의 형태로 page를 전달하고, 제목은 Title ${page}를, 그리고 url로는 /${page} 를 전달해주겠습니다.
코드를 불러오는 중 입니다 ...
 
이제 웹 페이지에서 1 페이지 보기, 2페이지 보기, 3페이지 보기 버튼을 눌러보면, 버튼을 누를 때마다 url이 변경되는 것을 확인할 수 있습니다. 그럼, 이번에는 뒤로 가기, 앞으로 가기 기능을 개발해봅시다. goBack 이라는 함수와 goForward라는 함수를 만들어주겠습니다. history api를 활용하면 뒤로 가기, 앞으로 가기 기능을 쉽게 개발할 수 있습니다. history 객체에는 back()과 forward()라를 내장 함수가 있는데요, 이 메서드들을 각각 goBack 함수와 goForward 함수의 내부에 작성한 다음, 코드를 실행해보겠습니다.
코드를 불러오는 중 입니다 ...
 
코드를 실행하면 이번에는 뒤로 가기, 앞으로 가기 버튼을 눌렀을 때, 페이지 주소들이 알맞게 변경되는 것을 볼 수 있습니다. 하지만, 버튼의 아래에 적힌 문구는 알맞게 변경되지 않고 있죠. 이번에는 이 문구도 알맞게 변경될 수 있도록 코드를 마저 작성해보겠습니다.
changePage 함수를 통해 페이지가 변경되었을 때, 이동한 페이지를 텍스트로 설정해주었고, 뒤로 가기나 앞으로 가기 버튼을 눌렀을 때 웹 페이지에 알맞은 문구를 나타내는 코드는 아직 작성해주지 않았습니다. 이 기능은 window 객체의 ‘popstate’라는 이베트를 사용해 개발할 수 있습니다.
history api는 이 popstate라는 이벤트를 제공합니다. 이는 히스토리 값이 변경될 때, 즉 뒤로 가기와 앞으로 가기 버튼을 눌렀을 때 발생되는 이벤트로, 다음과 같이 window.addEventListener를 사용해 사용할 수 있습니다.
popstate라는 이벤트가 발생할 때마다 실행되는 함수를 작성해보겠습니다. 매개변수로 event를 받고, 이 eventpushState를 통해 전달된 상태 객체입니다. 만약 전달 받은 event의 state값이 null이 아니라 존재한다면, 동일하게 id가 content인 요소를 가져온 다음, 이 요소의 text를 알맞은 문구로 설정해주겠습니다.
코드를 불러오는 중 입니다 ...
 
코드를 실행하고, 버튼들을 눌러 페이지 이동을 하고, 뒤로 가기, 앞으로 가기 버튼을 눌러보면, 주소와 문구가 알맞게 변경되는 것을 볼 수 있습니다.
 
이처럼 History API를 사용하면 SPA를 만들 때 페이지 전환 시에 페이지를 새로고침 하지 않고도 URL을 변경할 수 있으며, 사용자가 기대하는 대로 브라우저의 내비게이션 버튼이 작동하도록 만들 수 있습니다. 다음 시간에는 이 History API를 사용해서 기존에 개발했던 웹 페이지의 코드를 수정해보도록 하겠습니다. 감사합니다.
 
PREV4. MPA와 SPA
NEXT6. 동물 앨범 만들기-3