AOS 대응 | webview scroll memo - 웹뷰 스크롤 기억 못함 이슈

dev_hee·2022년 6월 16일
1

이슈해결

목록 보기
6/6

문제 발생

AOS 웹뷰에서 뒤로가기를 했을 경우, 웹 페이지 스크롤이 맨 위로 올라가면서 전체적으로 refresh 되었다.
이 때문에 스크롤이 기억되지 못하는 문제가 발생했다.

원인 분석

webview 에서 사용하는 App 의 정보들을 불러오는 getAppinfo 인터페이스 함수가 호출되면서 웹페이지가 다시 리로드 되었기 때문에 상단으로 스크롤 되었다.

이 경우를 AOS에서 해결한 문서를 찾아 앱팀께 문의 드려봤지만, 해당 코드도 이미 적용되어 있는 상황이었다.

문제 해결

따라서 sessionStorage 에 스크롤 위치를 저장한 뒤, 다시 해당 페이지에 접근하면 sessionStorage 에 저장된 스크롤 위치로 이동하는 Hook 을 생성했다.

localStorage 를 사용하지 않은 이유는, 웹뷰를 닫고 다시 해당 페이지에 접근한 경우에는 직전의 스크롤 위치로 이동되길 원치 않았기 때문이다.

useScrollMemo Hook

import { useEffect } from 'react';
import Scroll from 'react-scroll';

import { debounce } from 'lodash';

import { isAndroidApp } from '@common/webview';

export default function useScrollMemo(key: string): void {
  const handleScroll = debounce(() => {
    sessionStorage.setItem(key, `${window.scrollY}`);
  }, 300);

  const scrollToMemo = () => {
    const memoScroll = sessionStorage.getItem(key);
    if (!memoScroll) return;

    const scroll = Scroll.animateScroll;

    scroll.scrollTo(+memoScroll, {
      duration: 0,
      delay: 100,
    });
  };

  /** 스크롤 위치 기억 */
  useEffect(() => {
    if (!isAndroidApp()) return () => {};
    window.addEventListener('scroll', handleScroll);

    return () => {
      window.removeEventListener('scroll', handleScroll);
    };
  }, []);

  /** 스크롤 위치로 스크롤 */
  useEffect(() => {
    if (!isAndroidApp()) return;
    scrollToMemo();
  }, []);
}

window.scrollTo 대신 react-scroll

React DOM 의 동작 방식 때문인지 window.scrollTo 가 정상적으로 동작하지 않았다. 아무래도 리액트 컴포넌트들이 렌더링 된 이후에 스크롤이 되어야 하는데 window.scrollTo 가 렌더링 전에 호출되어서 문제였던 것 같다.

따라서 react-scroll 를 사용하였더니 정상적으로 스크롤 됨을 확인할 수 있었다.

사용법

  /** 스크롤 기억하기 */
  useScrollMemo(`eventDetail-${eventSeq}`);

useScrollMemo 에게 sessionStorage에 저장할 key 값을 전달해주면 된다.

profile
🎨그림을 좋아하는 FE 개발자👩🏻‍💻

0개의 댓글