알쓸FE팁 "웹스토리지 이벤트"

🗓 2023-04-18

Image by Miguel Á. Padriñán from Pexel

세션스토리지(sessionStorage), 로컬스토리지(localStorage)로 구성된 웹 스토리지는 이제 너무 익숙합니다.

다루기 힘들었던 쿠키와는 다르게 클라이언트 저장소로 사용 용도를 명확히 하고 더 나은 사용성으로 이미 우리의 친구가 됐죠.

프론트엔드 개발자가 자주 다루는 로컬 스토리지는 이런 것들을 할 수 있습니다.

  • storage.length
  • storage.key(n)
  • value = storage.getItem(key)
  • value = sotrage[key]
  • storage.setItem(key, value)
  • storage[key] = value
  • storage.removeItem(key)
  • delete storage[key]
  • storage.clear()

API가 잘 설계되어 있어서 이름만 보고 어떻게 동작하는지 금방 알 수 있습니다.

그런데 그거 아세요?

스토리지에 이벤트를 걸 수도 있다는 사실을요.

바로 웹 스토리지 이벤트(web storage event)입니다.

왜 쓸까?

스펙상으로는 아래와 같은 내용을 이벤트로 받을 수 있어요.

  • setItem()으로 아이템을 업데이트한 경우
  • removeItem()으로 아이템을 지운 경우
  • clear()로 모든 것을 지운 경우

즉, 로컬 스토리지에 생기는 변화를 감지해 특정 작업을 수행할 수 있습니다.

동일한 탭 혹은 동일한 윈도우 안에서는 이벤트가 발생하지 않고요. 서로 다른 탭, 윈도우에서만 이벤트가 발생합니다.

어떻게 쓸까?

이벤트를 거는 방법은 간단합니다.

window.addEventListener('storage', () => {
  console.log(JSON.parse(window.localStorage.getItem('sampleList')));
});

window.onstorage = () => {
  console.log(JSON.parse(window.localStorage.getItem('sampleList')));
};

우리가 로컬 스토리지를 사용할때 localStorage라는 싱글톤 객체를 이용하잖아요. 그러니까

localStorage.addEventListener('storage', ...);

이렇게 인스턴스에 직접 이벤트를 거는 사용법이 더 직관적이고 앞으로 확장이 더 용이하지 않을까 생각해 봤어요. storage라는 이벤트가 있다길래 앞뒤 안 가리고 저렇게 시도해 봤다가 안됐었거든요. 아마 저 말고도 몇 분 있을실 것 같아요. :)

StorageEvent 객체

다른 이벤트와 동일하게 스토리지 이벤트도 이벤트 객체를 받아서 정보를 얻을 수 있는데요. Event를 상속받는 StorageEvent는 아래와 같은 추가 정보를 갖고 있습니다.

  • key: 변경된 키값
  • newValue: 변경된 값
  • oldValue: 변경되기 직전의 값
  • storage: 변경된 스토리지(localStorage 혹은 sessionStroage)
  • url: 변경된 대상의 url

핸들러에서 일반 이밴트 객체처럼 사용할 수 있어요

window.addEventListener('storage', (ev) => {
  console.log(ev.key);
});

localStroage.setItem('myData', 'data1');

// console 출력: 'myData'

어디에 쓸까?

스토리지 이벤트는 다양하게 응용될 수 있을 것 같아요.

장바구니같이 쇼핑 중에 자주 사용되는 UI는 여러 탭에 열릴 가능성이 큰데요. 장바구니의 제품들을 주문해서 장바구니가 비워진 경우 쉽게 모든 탭에서 장바구니를 업데이트할 수 있을 것 같아요. 진입 시 업데이트나 폴링을 이용하는 것보다 UX에 더 좋겠죠.

다중 탭에서 서비스를 사용하는 유저가 한 탭에서 로그아웃을 시도한 경우 이벤트를 활용해 다른 탭도 동시에 로그아웃 상태로 바꾸는 구현도 할 수 있고요. 링크드 인이 이 방식을 사용하는 것 같더군요.

비슷한 맥락으로 탭 간의 실시간 동기화를 구현할 수 있을 것 같습니다. 이렇게 보니 탭 간의 이벤트 기반 메시지 교환 도구로 활용될 수 있겠네요.

♥ Support writer ♥
with kakaopay

크리에이티브 커먼즈 라이선스이 저작물은 크리에이티브 커먼즈 저작자표시-비영리-변경금지 4.0 국제 라이선스에 따라 이용할 수 있습니다.

© Sungho Kim2023