구현하고자 하는 기능
중복 코스 추가시 모달로 확인하기
PostSearchModat.tsx
const onClickAddCourse = (e: any, item: any) => {
const targetItem = {
name: item.place_name,
address: item.address_name,
road: item.road_address_name,
phone: item.phone,
id: item.id,
position: {
lng: item.x,
lat: item.y,
},
bounds: boundsInfo,
memo: "",
};
if(lists.filter((course:any) => {
if(course.id === item.id){
if (window.confirm("이미 등록한 코스입니다. 그래도 추가하시겠습니까?")) {
dispatch(addCourse(targetItem));
}
} else {
dispatch(addCourse(targetItem));
}
}))
};
lists
= 추가한 여행지 목록onClickAddCourse
= 검색 결과 중 하나를 클릭시 동작하는 함수. 검색 결과 클릭시 해당 장소를lists
에 추가.
confirm
반환 후 확인시 중복 코스를 추가하는 것까지는 정상적으로 작동하나 두 가지 문제가 발생했다.
1. 취소시에도 중복 코스가 추가된다.
lists
안에 0번부터 4번까지의 요소가 있다고 가정했을 때, onClickAddCourse
안에서의 lists
는 0번부터 3번까지의 요소만 존재한다. state
의 변경 순서 때문인데 정리하면 아래와 같다.
lists = []
일 때 onClickAddCourse
로 A 추가lists = [A]
일 때 onClickAddCourse
로 B 추가lists = [A, B]
일 때 onClickAddCourse
로 C 추가즉, onClickAddCourse
내에서는 dispatch
의 결과로 lists
에 targetItem
이 즉시 반영되는 것이 아니라, lists
가 먼저 존재하고 그 이후에 dispatch
를 실행하는 개념이다.
2. 중복 코스 추가시 배열의 길이만큼 추가된다.
반복문이기 때문
if (!lists.includes(targetItem)) {
dispatch(addCourse(targetItem));
} else {
if (window.confirm("이미 등록한 코스입니다. 그래도 추가하시겠습니까?")) {
dispatch(addCourse(targetItem));
}
}
위 1,2번 문제점을 모두 보완하고자 includes
를 사용했으나 예상치 못한 문제가 발생했다. 중복 코스의 경우에도 confirm
을 반환하지 않고 바로 추가되었다.
콘솔로 하나하나 찍어보니 lists
에 저장된 아이템의 position
과 targetItem
의 postion
이 불일치하기 때문에 발생한 이슈였다. targetItem
을 모아놓은 배열이 lists
인데 왜 불일치하는 건지 알 수가 없다... 리덕스에 저장되면서 타입이 변하지 않았을까 추측 중인데 정확한 원인은 모르겠다.
if ([...lists, targetItem].includes(targetItem)) {
if (
window.confirm("이미 등록한 여행지입니다. 그래도 추가하시겠습니까?")
) {
dispatch(addCourse(targetItem));
}
} else {
dispatch(addCourse(targetItem));
}
postion
이 여전히 불일치 한다는 이슈가 남아있지만 filter
메서드의 문제점만이라도 보완하기 위해 시도해보았으나 이번엔 또 다른 이슈가 발생했다. 중복 코스가 아님에도 불구하고 무조건 confirm
을 반환했다.
lists
의 마지막 요소가 업데이트 되지 않는 점을 보완하기 위해 [...lists, targetItem]
을 사용했는데 targetItem
은 검색 결과에서 유저가 선택한 장소이기 때문에 결과적으로 무조건 targetItem
을 포함할 수밖에 없다.
if (lists.some((course: any) => course.id === targetItem.id)) {
Swal.fire({
title: `이미 등록한 여행지입니다. \n 그래도 추가하시겠습니까?`,
icon: "question",
showCancelButton: true,
confirmButtonColor: "#B3261E",
cancelButtonColor: "#50AA72",
confirmButtonText: "네",
cancelButtonText: "아니오",
}).then((result) => {
if (result.isConfirmed) {
dispatch(addCourse(targetItem));
}
});
} else {
dispatch(addCourse(targetItem));
}
📌 mdn: Array.prototype.some()
마침내 성공했다....!! 사실상 filter
와 같은 로직이지만 반복문이 아니기 때문에 2번 이슈는 확실히 해결되었다. 그런데 1번은 어째서 해결된 건지 이해가 가지 않는다... filter
나 some
이나 둘 다 배열 메서드인데 왜 filter
에서는 lists
가 업데이트 되지 않고 some
에서는 잘만 되는지.....??? 🤔
진정한 개발자는 "이게 왜 되지?"를 겪었을 때라고 하던데 어느새 나도 "도약"해버린 건가.....