문제 상황
원했던 것 : task 컨테이너를 클릭했을 때 상세 페이지로 이동함. 버튼을 클릭했을 때는 navigate 되지 않음.
컨테이너 요소에 navigate를 걸어놓았을 때, 그 안의 버튼을 클릭하면 기능을 수행함과 동시에 페이지가 네비게이트 되어 원하는대로 실행되지 않는 문제. 이는 이벤트 버블링 때문에 발생하는 흔한 문제다.
TaskBox 내 버튼(StProgressButton) 클릭이 상위 컴포넌트 이벤트(handleDetailNavigate)를 트리거해 원치 않는 페이지 네비게이션을 발생시키는 것이었다.
해결 방안
이 문제를 해결하기 위해 이벤트 버블링을 방지하는 로직을 구현해야 한다. 버튼의 클릭 이벤트 핸들러 내에서 event.stopPropagation() 메서드를 호출함으로써, 해당 이벤트가 상위 컴포넌트로 전파되는 것을 막을 수 있다.
구현
1. 상태 토글 및 삭제 버튼에 이벤트 버블링 방지 추가
const handleStatusButtonClick = (id: string, event: React.MouseEvent<HTMLDivElement>) => {
event.stopPropagation();
dispatch(updateStoreTodo(id));
const newTodo = { isDone: !isDone };
updateMutation.mutate({ id, newTodo });
};
const handleDeleteButtonClick = (id: string, event: React.MouseEvent<HTMLDivElement>) => {
event.stopPropagation();
if (window.confirm('정말 삭제하시겠습니까?')) {
deleteMutation.mutate(id);
dispatch(deleteStoreTodo(id));
}
};
각 버튼의 이벤트 핸들러 함수에 첫 번째 인자로 event를 추가하고, 함수 내에서 event.stopPropagation()을 호출하여 이벤트가 상위 컴포넌트로 전파되지 않도록 한다. event.stopPropagation()을 추가하지 않으면 이벤트 버블링으로 인해 최상위 부모 요소인 TaskBox까지 이벤트가 전달되기 때문에 원하지 않았던 navigate가 실행된다.
2. 버튼 컴포넌트의 클릭 이벤트에 핸들러 수정 적용
<StProgressButton onClick={(event) => handleStatusButtonClick(item.id, event)}>
{item.isDone ? '되돌리기' : '완료'}
</StProgressButton>
<StProgressButton onClick={(event) => handleDeleteButtonClick(item.id, event)}>삭제</StProgressButton>
버튼 클릭 시 해당 이벤트 핸들러가 호출되도록 JSX에서 수정한다.
이러한 변경을 통해 StProgressButton을 클릭했을 때는 해당 버튼의 기능(상태 토글이나 삭제)만 실행되고, 상위 컴포넌트의 클릭 이벤트 핸들러가 호출되어 불필요한 페이지 네비게이션이 일어나는 것을 방지할 수 있다.
'Today I Learned' 카테고리의 다른 글
Next.js 개요 및 렌더링 이해하기 (0) | 2024.03.11 |
---|---|
Vercel 배포 시 push한 내역이 자동으로 반영되지 않을 때 (0) | 2024.03.08 |
useSearchParams 사용법 (0) | 2024.03.06 |
타입스크립트의 제네릭 이해하기 (0) | 2024.03.05 |
2024.03.04 TIL (0) | 2024.03.04 |