Todo.presenter.js
import React from "react";
import * as S from "./Todo.style";
import { faTrash } from "@fortawesome/free-solid-svg-icons";
function TodoPresenter({
todo,
handleRemoveTodo,
handleChangeTodoState,
handleSetModeEDIT,
}) {
return (
<S.Wrapper $state={todo.state} onClick={() => handleSetModeEDIT(todo.uuid)}>
<S.ContentsLeft>
<S.StateCircle
$state={todo.state}
onClick={(e) => {
handleChangeTodoState(e, todo.uuid);
}}
/>
</S.ContentsLeft>
<S.ContentsCenter>
<S.Title $state={todo.state}>{todo.title}</S.Title>
<S.DataWrapper>
<S.Date>시작 일: {todo.startDate}</S.Date>
<S.Date $right>종료 일: {todo.endDate}</S.Date>
</S.DataWrapper>
</S.ContentsCenter>
<S.ContentsRight>
<S.StateText>{todo.state}</S.StateText>
<S.StyledIcon
icon={faTrash}
onClick={(e) => {
handleRemoveTodo(e, todo.uuid); // 클릭 시 handleSetModeEDIT(todo.uuid) 도 수행됨
}}
/>
</S.ContentsRight>
</S.Wrapper>
);
}
export default TodoPresenter;
Todo.container.js 일부
const dispatch = useDispatch();
const handleRemoveTodo = (e, uuid) => {
dispatch(removeTodo(uuid));
dispatch(setModeADD());
};
const handleChangeTodoState = (e,uuid) => {
dispatch(changeTodoState(uuid));
};
const handleSetModeEDIT = (uuid) => {
dispatch(setModeEDIT());
dispatch(setSelectedDetails(uuid));
};
자식 요소인 S.StyledIcon 요소를 클릭하면 해당 요소의 onClick 이 수행되고
<S.Wrapper $state={todo.state} onClick={() => handleSetModeEDIT(todo.uuid)}>
의 onClick 이 이후에 수행되는 현상이 발생했다.
이벤트 버블링 현상 때문이다.
클릭 같은 이벤트가 발생하면 해당 요소에 바로 이벤트가 발생되는 것이 아니라
DOM Tree 를 따라 들어가면서 해당 요소를 찾아가고 이후 다시 DOM Tree를 탈출한다.따라들어가는 것을 이벤트 캡처링, 탈출하는 것을 이벤트 버블링이라고 한다.
React에서는 일반적으로 이벤트 캡처링 시 같은 이벤트 존재하더라도 발생하지 않는다.
즉, 이벤트 버블링 시에만 이벤트 핸들링 함수를 동작시킨다.
이러한 이유로 위 현상이 발생했던 것이다.
이벤트 전파를 막아주는 메서드
event.stopPropagation()
을 사용했다.
Todo.container.js 수정
const dispatch = useDispatch();
const handleRemoveTodo = (e, uuid) => {
e.stopPropagation(); // 추가
dispatch(removeTodo(uuid));
dispatch(setModeADD());
};
const handleChangeTodoState = (e,uuid) => {
e.stopPropagation(); // 추가
dispatch(changeTodoState(uuid));
};
const handleSetModeEDIT = (uuid) => {
dispatch(setModeEDIT());
dispatch(setSelectedDetails(uuid));
};