최근 프로젝트에서 두 개의 버튼 메뉴를 만들었습니다. 사용자가 어떤 페이지에 있는지에 따라 버튼의 활성화 상태를 변경해야 했죠. 처음에는 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>
);
}
주요 변경점
handleRouteChange
함수 추가: 현재 경로를 확인하고 그에 따라 버튼 상태를 설정하는 함수를 정의했습니다. 이 함수는 컴포넌트가 처음 마운트될 때와popstate
이벤트가 발생할 때 호출됩니다.- popstate 이벤트 리스너 추가: 브라우저에서 경로가 변경될 때 발생하는
popstate
이벤트를 감지하여handleRouteChange
함수를 호출합니다. 이를 통해 사용자가 뒤로 가기 버튼을 클릭하더라도 상태가 올바르게 업데이트 되도록 했습니다. - 클린업 함수 사용:
useEffect
의 클린업 함수에서removeEventListener
를 호출하여 컴포넌트가 언마운트될 때 이벤트 리스너를 제거함으로써 메모리 누수를 방지했습니다.
마무리
이번 수정 작업을 통해 Next.js에서 경로 기반 상태 관리를 안정적으로 구현할 수 있었습니다. 덕분에 사용자가 메뉴 버튼을 사용할 때 혼란을 겪지 않도록 개선할 수 있었죠. 이 과정에서 window 객체와 이벤트 리스너를 활용해 컴포넌트 상태를 효과적으로 관리할 수 있다는 것을 배웠습니다.
'나는 이렇게 학습한다 > Frontend' 카테고리의 다른 글
Intent URL로 Android 외부 브라우저로 리다이렉트하기 (1) | 2024.09.02 |
---|---|
Next.js 에서 iOS와 Android 사용자 핸들링 방법 (3) | 2024.09.02 |
JavaScript 로 단어 유효성 검사, 무의미한 단어 걸러내기 (0) | 2024.08.10 |
Tailwind CSS로 줄바꿈 방지와 긴 문자열 생략하기 (0) | 2024.08.07 |
TypeScript 타입 종류 한 번에 정리 (0) | 2024.08.06 |