[Main Project] UDog / 구현하기 - 컨펌 모달 구현하기

soohyunee·2023년 3월 12일
0

[Main Project] UDog

목록 보기
4/18

1. 구현하기

진행 상황

  • 컨펌 모달 추가

진행 예정

  • 1차 배포, 서버와 연결

2. TIL

컨펌 모달에 삭제 기능 추가

삭제 기능의 적절한 실행 지점 찾기

우선 강아지 정보 카드에는 삭제와 수정버튼이 있다. 내가 원하는 로직은 삭제 버튼을 클릭하면 컨펌 모달이 열리고, 컨펌 모달의 취소 버튼을 클릭하면 모달이 닫히고 삭제하기 버튼을 클릭하면 데이터가 삭제되는 것이었다.
프리 프로젝트에서는 컨펌 모달을 라이브러리로 사용해서 로직을 직접 짜지 않아 어떤식으로 구현하면 좋을지 감이 잘 잡히지 않았다.
모달은 리덕스로 상태를 관리하여 모달이 열리고 닫히는 것은 액션으로 정해두었고, 삭제 기능은 axios 커스텀 훅을 만들어 두어서 꺼내쓸 수 있게끔 구현해두었다.
우선 카드 컴포넌트의 삭제 버튼을 누르면 url을 매개변수로 삭제 커스텀 훅이 실행되고, set함수로 렌더링하고 있는 배열의 상태를 변경하게끔 구현해두어서 모달이 없을 때는 삭제와 함께 상태도 바로 업데이트가 되었다.

시도한 방법

처음 시도한 방법은 카드 컴포넌트의 삭제 버튼에는 디스패치로 모달 열림 액션을 실행시켰다. 컨펌 모달 컴포넌트의 취소 버튼에는 모달 닫힘 액션을, 삭제 버튼에는 삭제 커스텀훅을 배치했다. 그 결과 삭제 버튼을 클릭하면 모달이 실행 되어야하는데 모달이 열리지 않고 useNavigate 관련 에러가 떴었다.

두번째 방법은 카드 컴포넌트의 삭제 버튼에는 삭제 커스텀 훅을 배치했고,삭제 커스텀 훅에 디스패치로 컨펌 모달 액션을 적용하였다. 그 결과 모달이 열리긴 했으나 열리자 마자 삭제가 되어버렸다.

해결 방법

삭제 기능은 컨펌 모달의 삭제 버튼에 위치하는 게 맞겠다는 생각이 들었다. 그래서 우선 처음 시도한 방법으로 돌아가서 해당 에러를 해결하고자 커스텀 훅에서 useNavigate 부분을 살펴보았다. 해당 부분은 post와 patch에서 사용하고 있었다. 검색을 해보니 useNavigate는 라우터로 관리되고 있는 컴포넌트에서만 사용이 가능해서 import할 때 해당 부분 때문에 에러가 나는 것 같았다. 그래서 navigate가 없는 delete는 따로 분리하여 커스텀훅으로 만들었다.
그리고 카드 컴포넌트의 삭제 버튼에는 모달 열림 액션을 디스패치로 실행 시켰다. 삭제관련 리듀서를 만들어서 카드 컴포넌트의 삭제 버튼을 눌렀을 때 url의 상태를 업데이트 하게끔 추가해주었다.

	const handleOpenConfirmModal = () => {
		dispatch(
			openModal({
				modalType: 'DogConfirmModal',
				isOpen: true,
			})
		);
		dispatch(deleteUrl(`/mydog/${dog.id}`));
	};

컨펌 모달에서 useSelector로 업데이트한 url을 꺼내오고, 삭제 버튼을 누르면 삭제 커스텀 훅에 url을 담아서 실행시켰다.

const {url} = useSelector(selectDelete);
const {DELETE} = useDelete(url);

const onClickDelete = () => {
		DELETE();
	};

삭제 후에 모달이 닫혀야 하는데 삭제에 실패해도 닫혀야하므로 promise의 finally 메소드를 사용해주었다. 해당 메소드는 Promise가 처리되면 충족되거나 거부되는지 여부에 관계없이 지정된 콜백 함수가 실행된다. Promise가 성공적으로 수행 되었는지 거절되었는지에 관계없이 Promise가 처리 된 후에 코드가 무조건 한 번은 실행되는 것을 제공하는 메소드이다.

	const DELETE = () => {
		API.delete(url, {
			headers: {
				Authorization: token,
				Refresh: refresh,
			},
		})
			.then((res) => {
				console.log('삭제성공', res);
			})
			.catch((err) => {
				console.log(err);
			})
			.finally(() => {
				dispatch(closeModal());
			});
	};
profile
FrontEnd Developer

0개의 댓글