[React] 모바일 환경에서의 뒤로가기, popstate

게코젤리·2023년 4월 2일
0
const NavItem = styled.li<{ isClicked: boolean | null }>`
  color: ${(props) =>
    props.isClicked ? props.theme.white.darker : props.theme.gray};
`;
const navigate = useNavigate();
const [navDataArr, setNavDataArr] = useState([
  { name: '홈', url: 'home'},
  { name: '평가한 영화', url: 'rate' },
  { name: '찜한 영화', url: 'favorite' },
]);
const onClickNavItem = (url: string) => () => navigate(`/${url}`);


<ul>
  {navDataArr.map((item) => (
    <NavItem
      key={item.url}
      onClick={onClickNavItem(item.url)}
      isClicked={location.pathname === `/${item.url}`}
      >
      {item.name}
    </NavItem>
  ))}
</ul>

네비 메뉴를 만들었다. useLocation훅으로 현재 url과의 일치 여부를 판단하여 일치할 경우 폰트 색을 바꿔 활성화되어 보이게 했다. 간단한 로직이었고 PC브라우저에선 예상한 대로 구현이 되었다. 그런데 모바일 환경에선 특정 페이지로 이동했다가 뒤로 가기를 누르면 두 개의 버튼이 활성화되는 문제가 생겼다.

  1. 모바일 브라우저는 상대적으로 더 적은 시스템 리소스를 가지고 있기 때문에 브라우저의 기능인 '뒤로가기'시에 상태변경이 일어나지 않을 수 있음.
  2. popstate 이벤트 리스너를 이용해서 브라우저 히스토리가 변경될 때마다 상태가 업데이트될 수 있도록 코드를 수정.
  • popstate : 브라우저 히스토리가 변경될 때 발생하는 이벤트.
  • 브라우저 히스토리 : 주소창에 표시되는 URL, 페이지 제목과 페이지가 로드된 시점의 정보 등 -> 사용자가 방문한 웹 페이지들의 기록.
useEffect(() => {
    const updateNavDataArr = () => {
      setNavDataArr((prev) =>
        prev.map((item) => ({
          ...item,
          isClicked: location.pathname === `/${item.url}`,
        }))
      );
    };
  
    updateNavDataArr(); // 첫 렌더링 시 상태 업데이트
    // popstate 이벤트 리스너 추가
    window.addEventListener('popstate', updateNavDataArr);
    // 이벤트 리스너 정리
    return () => {
      window.removeEventListener('popstate', updateNavDataArr);
    };
  }, [location]);

0개의 댓글