sessionStorage 사용기
✨ sessionStorage 사용기
오늘은 업무에서 sessionStorage를 사용했었는데, 과정을 정리해보고자 한다.
🚨문제 정의
💡 사용자가 특정 B페이지에 접속하면 자동으로 스크롤 이벤트가 일어나야 한다.
위의 내용을 바탕으로 간단하게 해당 구현해야 할 기능을 정의해보자면, 아래와 같다.
- Trigger: 사용자가 B페이지 접속
- Event: Scroll
이렇듯 기능 정의 자체는 크게 어려운 것이 없었으나..😂 사용자가 B페이지에 접속하는 방법은 (당연히) 많을 수 밖에 없고, 접속하는 방식에 따라 표시되는 내용이 다르기 떄문에 이벤트 구현 세부사항이 다를 수밖에 없었다.
일단 내가 생각한 사용자의 B 페이지 접속 루트는 아래와 같았다.
- A에서 B로 접속
- A 제외 페이지에서 B로 접속
- URL 입력하여 B 바로 접속
- B에서 새로고침
- (또 다른게 있을 수도…)
여기서 1차로 구분되어야 하는건 사용자가 A페이지에서 넘어온 것인지, 아님 그 외의 페이지에서 B로 넘어온 것인지 였다.
1️⃣ 1차 시도, #해시
1차 아이디어는 URL의 해시(#)를 사용하는 방식이었다. A 페이지에서 B페이지로 넘어올 때는 router.push
를 이용하는 것이기 때문에 push할 때 #new
를 붙인 url을 사용한다면 해당 페이지가 A에서 넘어온 것을 알 수 있을 것이었다!
또 hash값이 존재하는지 확인하는 useHash
라는 custom Hook도 이미 만들어 둔 상태였다.
사실 1차 방법에서 나는 진짜 탁월한(…) 아이디어라 생각하고 나름 뿌듯해했으나 문제는 B에서 새로고침 하던 상황이었다.
사실 처음에 해당 부분까진 고려를 못했기에 문제가 없었으나(…) 조금만 더 생각해보면 문제가 있음을 알 수 있다.
- A 페이지에서
#new
해시값을 붙여 B페이지로 보냄 - B 페이지에 작성된 코드는
#new
를 보고 이 페이지가 A에서 이동한 것이라 판단함 - 이 때 사용자가 ‼️새로고침 함
#new
페이지에서#new
페이지로 접속함
마지막을 자세히 살펴보자.
새로고침 직전의 페이지는 B페이지 자신이므로, 이전 페이지는 A 페이지가 아니다. 따라서, #new
를 사용하면 잘못된 이벤트 trigger가 작동하게 되는 것이다!
2️⃣ 2차 시도, sessionStorage
이 난관을 어찌 해결할 것인가…😣 에 대해서 고민하다다, 사용자의 브라우저 탐색기록을 저장해두었다가 사용하면 되지 않을까? 생각했다.
최초에는 나에게 익숙한 localStorage
를 먼저 떠올렸으나 localStorage는 (반)영구적인 데이터 저장소기 때문에, 사용자가 탭을 닫거나 하는 등 변수가 늘어나게 되어, 그동안은 써보지 않았던 sessionStorage
를 사용하게 되었다!
✨sessionStorage
세션스토리지가 무엇인지 먼저 MDN을 기반으로 이해해보자.
sessionStorage는 특정 탭에서만 유지되는 저장소로, 탭이나 창을 닫으면 데이터가 삭제된다!
🔸sessionStorage VS localStorage
그렇다면 localStorage와의 차이점은 무엇일까?
클라이언트 측(브라우저)에 데이터를 저장할 수 있는 기능을 제공한다는 점은 동일하지만, 데이터 지속성에서 차이가 발생한다.
구분 | localStorage | sessionStorage |
---|---|---|
데이터가 유지되는 기간 | 반영구 (사용자 직접 제거 or JS로 제거할 때까지 유지) | 세션 단위 (탭/창 닫으면 삭제) |
브라우저 종료시 데이터 | 유지됨 | 삭제 됨 |
✅ 해결 방안
그래서 최종적인 구현 흐름은 다음과 같다!
- A 페이지로 접속할 때
sessionStorage.setItem("page", "A")
를 실행하여 현재 페이지가 A임을 저장한다.
B 페이지로 이동할 때
sessionStorage.getItem("page")
를 확인하여 이전 페이지가 A였는지 확인한다.- 이전 페이지가 A였다면 특정 이벤트를 발생시킨다.
- 이후
sessionStorage.setItem("page", "B")
를 실행하여 현재 페이지를 B로 변경한다. - 이 상황에서는 A > B 상황의 스크롤 이벤트를 발생시킨다.
B 페이지에서 새로고침 시
sessionStorage
는 페이지를 새로고침 하더라도 데이터가 유지되므로, 값은 설정해 둔 B로 남아있다.- 따라서, 사용자가 새로고침 했을때도 이전 페이지가 B임을 인지할 수 있다.
- 이 상황에서는 B > B 상황의 스크롤 이벤트를 발생시킨다.
⛔구현 중 추가 오류
위의 트리거는 sessionStorage를 이용해 무사히 해결하였으나, 새로운 문제가 발생했으니, 스크롤 이벤트를 주는 와중에 overflow-hidden
으로 설정해두었으나 자식 요소가 스크롤 되는 순간 페이지가 흔들리는 (약간 스크롤이 되어버리는) 문제가 발생했다. 😣
특정 요소가 페이지 안에 진입해야 하므로 scrollInToView
를 사용하는데, 원하는 컴포넌트 뿐만 아니라 그 밖의 컴포넌트까지 스크롤되는 듯 하여, scrollbar-hide
를 전부 풀고 어디서 스크롤이 발생하는지 살펴보았다.
문제는 해당 요소도 size
, overflow-hidden
모두 정확히 설정되어 있었던 것이었다…
1️⃣ 1차 시도
그래서 1차 시도로 스크롤을 고정시키는 방안을 생각했다. 아예 움직이지 못하도록 scrollTo(0,0)
를 시도하였으나 의도한 대로 작동하지 않았다…
2️⃣ 2차 시도
스크롤 자체를 막는건 overflow-hidden
을 이용하고 있었기 때문에 해당 요소가 문제가 될까? 라는 생각이 들어 MDN 사이트를 참고해, overflow-clip
을 주어 해결했다.
🔸 overflow-clip
VS overflow-hidden
구분 | overflow-clip | overflow-hidden |
---|---|---|
콘텐츠가 넘어갈 때 | 스크롤 생성하지 않음 | 스크롤을 숨김 |
콘텐츠 접근성 | 접근 불가 | 감지 가능 |
사용 예시 | 정확한 사이즈 유지 | 부모 요소 크기는 고정이나 내부 스크롤이 가능해야 할 때 |
즉, overflow-clip은 넘치는 콘텐츠를 아예 무시하는 것으로 이해하면 된다.
✨참고!
overflow-clip
을 작성했을 때, 자동 formmating 되어 저장되는 tailwind library의 문제로overflow-clip
을text-clip
으로 변경해 저장되어, 이부분은global.css
에 작성하였다.
🥳 마무리
오랜 시간동안 공들인 이벤트 구현이 끝이났다! 글에는 굉장히 간단하게 썼지만 실제로는 해당 이벤트가 일어나면서 발생해야 하는 주변 state관리라던가, 스크롤을 적절히 움직이기 위한 계산 방식이라던가 구현하는 동안 많을 고민과 코드를 쓰고 지우고(…)하는 과정들이 있었다.
하지만 FE 개발자는.. 일단 사용자를 생각하는게 먼저 아니겠는가!!! (ㅎㅎ)
스크롤 이벤트는 현재 프로젝트의 기능자체에는 큰 영향을 주는 것이 아니었으나, 사용성에 큰 영향을 주는 작업인 만큼 포기하거나 우회하고 싶지 않았다. 🤗
그만큼 난이도가 있었지만 너무 만족스럽고 뿌듯했던 작업이었다.
이제 프로젝트도 1차 beta 버전이 마무리 되어간다. 계속 파이팅해보자✨