픽하면 '보드게임을 pick 했어요' 픽을 취소하면 '보드게임 pick을 취소했어요'라는 toast popup이 뜨는 것을 구현해야했다.
toast popup을 2초간 지속되었다가 사라지도록 구현시켰다.
그런데 그 2초간의 시간 안에 사용자가 연속으로 누르게되었을 때 그때마다 픽/픽 취소가 바뀌면서 나오지 않는 문제가 발생한다..
처음 나온 toast popup이 계속 뜰 뿐.
꼼수 1)
이걸 2초동안은 클릭 못하게 막아하나 싶어
isClicked라는 상태변화함수로 클릭을 못하도록 막았다.
그런데 2초안에 연속으로 눌렀을때 아무것도 작동안하니
사용자입장에서 답답하다고 느낄 것 같았다..
꼼수 2)
그럼 2초동안 기다리라는 문구를 넣어야하나 싶기도 하면서..
굳이스럽기도하고..
그래서 좋아요 요소가 필수적으로 들어가는 쇼핑몰들은 어떻게 기능을 구현했는지 살펴보았다.
대표적으로 '무신사', '지그재그', '에이블리'를 살펴보았다.
'무신사', '에이블리'
좋아요를 눌렀을때만 좋아요했다는 popup이 뜨고 취소했을 때는 팝업은 뜨지않고 좋아요 하트 색상이 없어지기만 하는 형태였다.
'지그재그'
썸네일에서 좋아요를 누를때와 상품 안에서 좋아요 누를때랑 다르게 볼 수 있는었는데
썸네일에서 좋아요를 누를때는 좋아요를 누를때 취소할때마다 계속해서 해당 팝업이 뜬다. (내가 구현하고 싶던 것..)
상세페이지안에서는 좋아요가 하단에 존재에 popup이 뜨면 다시 누를 수가 없는 형태였다.
살펴본 결과!
내가 구현하고자 하는 게 코드를 수정하면 가능은 한 일이구나를 깨닫기는 했다..ㅋㅋㅋㅋ
해당 코드는 좀 더 고민해봐야겠다..
방법을 찾았다.
pick했을때와 안했을때 상태를 구분시켜서 작동시키면 되려나 하고 해봤더니.. 되네ㅎㅎ
생각보다 심플한 방법이라 머쓱하다..
(redux를 활용한 코드입니다)
toast: {
pick: false,
unpick: false,
},
pickedItems: {},
case "SET_TOAST_PICK":
return {
...state,
toast: {
...state.toast,
pick: action.payload,
},
};
case "SET_TOAST_UNPICK":
return {
...state,
toast: {
...state.toast,
unpick: action.payload,
},
};
case "SET_IS_PICKED":
return {
...state,
pickedItems: {
...state.pickedItems,
[action.payload.id]: action.payload.isPicked,
},
};
이런식으로 나눠서 상태관리를 진행했다.
이렇게 했더니 toast popup이 뜨면서 isPicked값에 따라 문구가 바뀌는 형태가 바뀌었다.
const isPicked = useSelector((state) => state.pickedItems[id] || false);
const toastPick = useSelector((state) => state.toast?.pick);
const toastUnPick = useSelector((state) => state.toast?.unpick);
const setToastPick = (value) => {
dispatch({
type: "SET_TOAST_PICK",
payload: value,
});
};
const setToastUnpick = (value) => {
dispatch({
type: "SET_TOAST_UNPICK",
payload: value,
});
};
useEffect(() => {
if (toastPick) {
const timer = setTimeout(() => {
setToastPick(false);
}, 2000);
return () => clearTimeout(timer);
}
if (toastUnPick) {
const timer = setTimeout(() => {
setToastUnpick(false);
}, 2000);
return () => clearTimeout(timer);
}
}, [toast, setToastPick, setToastUnpick]);
{isPicked ? (
<div className={`toast ${toastPick ? "pop" : ""}`}>
<ToastPopUp ToastContent={"보드게임을 PICK 했어요"} />
</div>
) : (
<div className={`toast ${toastUnPick ? "pop" : ""}`}>
<ToastPopUp ToastContent={"보드게임 PICK을 취소했어요"} />
</div>
)}