TIL18. history API

imloopy·2022년 4월 7일
0

Today I Learned

목록 보기
18/56
post-custom-banner

Today I Learned

오늘은 클라이언트단에서 서버에 페이지를 요청하지 않고 주소를 이동하고 렌더링할 수 있는 history API에 대하여 공부했다.

history API

DOM의 Window 객체는 history 객체를 통해 브라우저의 세션 기록에 접근할 수 있는 방법을 제공합니다. history는 사용자를 자신의 방문 기록 앞과 뒤로 보내고 기록 스택의 콘텐츠도 조작할 수 있는, 유용한 메서드와 속성을 가집니다.

우리는 어떤 링크를 클릭했을 때, 해당 서버의 html로 요청하는 것이 아닌, history API를 이용하여 페이지만 이동시킬 수 있다.

const $btn1 = document.createElement("button");
$btn1.textContent = "1로 이동하기";
$btn1.addEventListener("click", () => {
  history.pushState(null, "", "/product/1");
});
const $btn2 = document.createElement("button");
$btn2.textContent = "2로 이동하기";
$btn2.addEventListener("click", () => {
  history.pushState(null, "", "/product/2");
});

const $body = document.querySelector("body");
$body?.appendChild($btn1);
$body?.appendChild($btn2);

이 코드를 실행하면 -> 주소창에 주소가 변경되는데, 실제로 새로고침되지 않음을 알 수 있다.
이 상태에서 뒤로가는 버튼을 누를 경우, 아무것도 변경되지 않는다. 우리는 pushstate를 통해 버튼을 누를 때 이동하도록 했지만, 뒤로가는 이벤트를 감지하도록 설정하지 않았기 때문이다.

window.addEventListener('popstate', () => {
  // 다시 화면에 렌더링하도록 반영하기
  route();
});

화면에 반영하기 위하여 window 객체에 popstate 이벤트리스너를 등록하고, 뒤로 가는 동작이 감지되면 그 주소에 맞게 다시 렌더링하는 과정을 거쳐야한다. 이것이 기본적인 SPA(Single Page Application) 동작 방식이다.

만약 이 상태에서 새로고침을 하면 어떻게될까? 오류가 나거나 아무것도 나오지 않는다. 기본적으로는 index.html이 다시 실행되기 때문에, index.js를 처음 불러올 때 route 과정을 거치도록 설정해 주어야 한다.

// index.js
// psuedocode 입니다.
import { App } from './App.js'

new App()

// App.js
class App {
  constructor() {
    // 처음 불러올 때 주소에 맞게끔 분기하는 역할
    this.router()
    
    // 이벤트 등록
    window.addEventListener('pushstate', () => {
      this.router()
    });
   
   // 이벤트 등록
    window.addEventListener('popstate', () => {
      this.router()
    });
  }
  
  route() {
    const { pathname } = location
    if (pathname ==== '/') {
    // render home page
    } else if (pathname.indexOf('pathname') > 0) {
      // render product page
    } else {
      // render error 404 page
    }
}

location.href와 차이

  • location.href = “어떤 주소” 는 실제 주소를 옮기기 때문에 화면의 내용이 모두 사라지는 효과가 있다.
  • history.pushState는 실제 주소의 이동 없이 화면의 변경만 이루어지게 할 수 있다.

마치며

그 동안 React의 useHistory 만 사용하여 기본적인 동작 원리에 대해 전혀 모르고 사용하고 있었으며, 바닐라 자바스크립트도 라우팅을 설정하여 SPA를 구성할 수 있음을 알았다. 또, 생각보다 바닐라 자바스크립트로 SPA를 구성하기에는 이것 저것 설정해주어야 될 것이 많았다. 아 이래서 프레임워크를 쓰는구나...?

출처

https://developer.mozilla.org/ko/docs/Web/API/History_API

post-custom-banner

0개의 댓글