나는 이렇게 학습한다/Frontend

Next.js 컴포넌트에서 URL 경로 기반 상태 관리

daco2020 2024. 8. 15. 00:01
반응형

최근 프로젝트에서 두 개의 버튼 메뉴를 만들었습니다. 사용자가 어떤 페이지에 있는지에 따라 버튼의 활성화 상태를 변경해야 했죠. 처음에는 useState로 두 버튼의 상태를 관리했어요. 하지만 사용자가 뒤로 가기 버튼을 클릭할 때 상태가 제대로 업데이트되지 않는 문제가 발생했습니다.

 

[유의어 반의어 찾기] 버튼이 활성화 되었지만 실제 페이지는 [그 단어 뭐였더라?] 페이지를 가리키고 있었죠.

 

 

문제

기본적인 상태 관리는 다음과 같은 방식으로 이루어졌습니다:

const [selectedButton, setSelectedButton] = useState(1);

const handleClick = (buttonId) => {
  setSelectedButton(buttonId);
};

 

이 방식은 버튼을 클릭할 때는 잘 동작했지만, 사용자가 뒤로 가기 버튼을 눌렀을 때는 selectedButton 상태가 경로에 따라 업데이트되지 않는 문제가 있었습니다.

 

 

useRouter 시도와 실패

이 문제를 해결하기 위해 Next.js의 useRouter 훅을 사용하려 했지만, NextRouter was not mounted 오류가 발생하며 훅을 사용할 수 없었습니다. 이 오류는 useRouter가 아직 마운트되지 않았을 때 호출되는 문제로 결국 해결하지 못했습니다.

 

 

window 객체를 활용한 해결 방법

useRouter를 사용하지 못하는 상황에서, 브라우저의 window 객체를 활용해 현재 경로를 직접 가져오면 되겠다 싶었습니다. popstate 이벤트를 통해 경로 변경을 감지하는 방법을 사용하여 아래처럼 최종 수정했죠.

"use client";

import Link from "next/link";
import { useEffect, useState } from "react";

export default function Header() {
  const [selectedButton, setSelectedButton] = useState(1);

  useEffect(() => {
    const handleRouteChange = () => {
      const currentPath = window.location.pathname;

      if (currentPath === "/") {
        setSelectedButton(1);
      } else if (currentPath === "/find-word") {
        setSelectedButton(2);
      }
    };

    // 컴포넌트가 마운트될 때 현재 경로를 설정
    handleRouteChange();

    // popstate 이벤트를 감지하여 경로 변경을 처리
    window.addEventListener("popstate", handleRouteChange);

    // 컴포넌트 언마운트 시 이벤트 리스너 제거
    return () => {
      window.removeEventListener("popstate", handleRouteChange);
    };
  }, []);

  return (
    <header>
      <nav>
        <Link href="/">
          <button
            onClick={() => setSelectedButton(1)}
          >
            유의어 반의어 찾기
          </button>
        </Link>

        <Link>
          <button
            onClick={() => setSelectedButton(2)}
          >
            그 단어 뭐였더라?
          </button>
        </Link>
      </nav>
    </header>
  );
}

 

 

주요 변경점

  1. handleRouteChange 함수 추가: 현재 경로를 확인하고 그에 따라 버튼 상태를 설정하는 함수를 정의했습니다. 이 함수는 컴포넌트가 처음 마운트될 때와 popstate 이벤트가 발생할 때 호출됩니다.
  2. popstate 이벤트 리스너 추가: 브라우저에서 경로가 변경될 때 발생하는 popstate 이벤트를 감지하여 handleRouteChange 함수를 호출합니다. 이를 통해 사용자가 뒤로 가기 버튼을 클릭하더라도 상태가 올바르게 업데이트 되도록 했습니다.
  3. 클린업 함수 사용: useEffect의 클린업 함수에서 removeEventListener를 호출하여 컴포넌트가 언마운트될 때 이벤트 리스너를 제거함으로써 메모리 누수를 방지했습니다.

 

 

마무리

이번 수정 작업을 통해 Next.js에서 경로 기반 상태 관리를 안정적으로 구현할 수 있었습니다. 덕분에 사용자가 메뉴 버튼을 사용할 때 혼란을 겪지 않도록 개선할 수 있었죠. 이 과정에서 window 객체와 이벤트 리스너를 활용해 컴포넌트 상태를 효과적으로 관리할 수 있다는 것을 배웠습니다.

반응형