티스토리 뷰
* 가장 하단에 참고 블로그가 있습니다. 참고한 블로그를 보고 제가 이해한 대로 재작성 하였습니다. 제가 이해한대로 작성하였으니 잘 모르시겠다면 하단에 참고 블로그를 확인해주세요. 간단 명료하게 잘 작성해주셨습니다.
전역상태 관리로 zustand를 사용하고 있어 zustand를 이용해 컨펌창을 만들어보려고 한다.
confirm() 을 호출하면 기대하는 동작
1. confirm 다이얼로그 띄우기
2. 다이얼로그가 닫히면 결과 반환.
confirm 다이얼로그를 띄우기 위해서는 modal과 같이 boolean값으로 상태를 변경시키고,
상호작용이 끝나는 시점에 결과 값을 받기 위해서는 ` Promise `(대기, 완료, 실패) 되었을때 그 결과를 ` resolve `를 통해 반환받으면 된다.
confirm창의 동작을 관리하는 커스텀 훅 만들기
1. interface를 이용해 confirm 상태 정의하기
message: string;
confirm창을 사용하는 곳마다 다른 메시지를 보여줄 수 있도록 하기위해 작성.
showDialog: boolean;
confirm창의 보이기/숨기기를 관리할 수 있도록 boolean 값으로 작성
confirm: (message?: string) => Promise<boolean>;
사용자에게 메시지를 표시하고 사용자에게 true 또는 false를 Promise로 반환하는 함수
onClickOK: () => void;
onClickCancel: () => void;
사용자가 true 또는 false를 클릭했을 때 실행되는 함수
2. confirm 훅 만들기
export const useConfirmStore = create<ConfirmState>((set) => ({
}));
create를 사용하여 set을 통해 매개변수를 받을 수 있도록 해주면 된다.
message: "",
showDialog: false,
message의 초기상태는 `" "`빈문자열, showDialog의 초기상태는 `false`로 설정해 기본적으로 보이지 않게 하자.
이제 message를 매개변수로 받고, Promise를 반환할 수 있는 함수를 만들어 주어야 한다.
confirm: (message) => {
return new Promise((resolve) => {
set({
message: message ?? "",
showDialog: true,
onClickOK: () => {
set({ showDialog: false });
resolve(true);
},
onClickCancel: () => {
set({ showDialog: false });
resolve(false);
},
});
});
},
onClickOK: () => {},
onClickCancel: () => {},
confirm은 message를 매개변수로 받고 Promise를 반환한다.
set을 통해 message를 매개변수로 받고 showDialog를 true가 된다.
`onClickOK` 이 클릭되었을 때 true를 반환하고 confirm창을 숨기게한다.
`onClickCancel` 이 클릭되었을 때 false를 반환하고 confirm창을 숨기게 한다.
<confirm 훅 전체코드>
import { create } from "zustand";
//컨펌 훅
interface ConfirmState {
message: string;
showDialog: boolean;
confirm: (message?: string) => Promise<boolean>;
onClickOK: () => void;
onClickCancel: () => void;
}
export const useConfirmStore = create<ConfirmState>((set) => ({
message: "",
showDialog: false,
confirm: (message) => {
return new Promise((resolve) => {
set({
message: message ?? "",
showDialog: true,
onClickOK: () => {
set({ showDialog: false });
resolve(true);
},
onClickCancel: () => {
set({ showDialog: false });
resolve(false);
},
});
});
},
onClickOK: () => {},
onClickCancel: () => {},
}));
confirm창 컴포넌트 만들기
const { message, showDialog, onClickOK, onClickCancel } = useConfirmStore();
만들어둔 confirm 훅을 import해온다.
if (!showDialog) return null;
confirm창이 flase인 경우 null을 반환해 confirm창을 렌더링하지 않고 조건적으로 보여줄 수 있도록 한다.
<div className="fixed inset-0 bg-black bg-opacity-40 z-40"></div>
confirm창이 보였을 때 다른 부분은 선택되지 않을 수 있도록 confirm창 뒤로 div를 깔아준다.
<div className="px-8 py-8 md:py-10 md:px-10 bg-white rounded-md">
<p className="flex justify-start items-center text-black text-lg">
{message}
</p>
<div className="flex flex-row justify-end gap-4 mt-10 w-full md:h-10">
<button
className="hover-color w-20 md:w-24 font-semibold border whitespace-nowrap border-border-color px-4 py-1 rounded-md"
onClick={onClickCancel}
>
아니오
</button>
<button
className="bg-point-color md:w-24 font-semibold text-black hover-color w-20 border whitespace-nowrap border-border-color px-4 py-1 rounded-md"
onClick={onClickOK}
>
예
</button>
</div>
</div>
실제 confirm창이 될 div 부분을 그려주면 된다.
<p className="flex justify-start items-center text-black text-lg">
{message}
</p>
confirm훅에서 만들어둔 messeage를 보여주고
<button
className="hover-color w-20 md:w-24 font-semibold border whitespace-nowrap border-border-color px-4 py-1 rounded-md"
onClick={onClickCancel}
>
아니오
</button>
아니오를 보여주는 버튼에는 onClickCancel을 주고
<button
className="bg-point-color md:w-24 font-semibold text-black hover-color w-20 border whitespace-nowrap border-border-color px-4 py-1 rounded-md"
onClick={onClickOK}
>
예
</button>
예를 보여주는 버튼에는 onClickOK를 주면 끝!
confirm 컴포넌트 전체코드
import { useConfirmStore } from "@/store/commenStore";
import React from "react";
export default function DoubleCheckConfirm() {
const { message, showDialog, onClickOK, onClickCancel } = useConfirmStore();
if (!showDialog) return null;
return (
<>
<div className="fixed inset-0 bg-black bg-opacity-40 z-40"></div>
<div
className="overflow-hidden bg-white rounded-3xl fixed left-1/2 transform -translate-x-1/2 z-50 w-80 md:w-[480px]"
style={{ top: "16%" }}
>
<div className="px-8 py-8 md:py-10 md:px-10 bg-white rounded-md">
<p className="flex justify-start items-center text-black text-lg">
{message}
</p>
<div className="flex flex-row justify-end gap-4 mt-10 w-full md:h-10">
<button
className="hover-color w-20 md:w-24 font-semibold border whitespace-nowrap border-border-color px-4 py-1 rounded-md"
onClick={onClickCancel}
>
아니오
</button>
<button
className="bg-point-color md:w-24 font-semibold text-black hover-color w-20 border whitespace-nowrap border-border-color px-4 py-1 rounded-md"
onClick={onClickOK}
>
예
</button>
</div>
</div>
</div>
</>
);
}
실제 사용하는 곳(일부)
import DoubleCheckConfirm from "../common/DoubleCheckConfirm";
const handleDelete = async () => {
const isConfirmed = await confirm("정말 삭제하시겠습니까?");
if (isConfirmed) {
deleteHomeDetailMutate(id);
router.replace("/category/re-home");
}
};
return <DoubleCheckConfirm />
async await을 이용해 confirm을 사용하면 된다.
async, await 을 사용하는 이유는 confirm 함수가 Promise<boolean>을 반환하기 때문에 결과를 기다리고 처리하기 위해 사용한다!
참고 블로그 ( https://velog.io/@foreknowledge/React-%EC%BB%B4%ED%8F%AC%EB%84%8C%ED%8A%B8%EB%A1%9C-alert-confirm-prompt-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0 )
'TIL' 카테고리의 다른 글
react-hook-form 나홀로 정리하기 (0) | 2024.07.02 |
---|---|
무한스크롤 쉽게 구현하기 (0) | 2024.06.25 |
Axios에서 url 요청보낼 때 주의할 점 (0) | 2024.06.07 |
Next.js Image tag 사용하기 (0) | 2024.06.07 |
axiosInstance 작성해보기(accessToken, refreshToken) (0) | 2024.05.22 |
- Total
- Today
- Yesterday
- Fetch와 Axios 의 장단점
- simple Icon 사용방법
- Warning: A component is changing an uncontrolled input to be controlled.
- axios instance 작성하기
- readme작성해보기
- 에러모음집
- axiosinstance 사용 시 토큰 사용 법
- 영화 별점
- git cache
- 유효성검사 css
- 영화별점만들기
- readme 역할
- styled component 조건부 사용방법
- styled component 설치방법
- axios 사용하기
- nextjs 토큰 만료처리하기
- 별점만들기
- Warning: validateDOMNesting(...): <li> cannot appear as a descendant of <li>
- 유효성검사
- 별점 색채우기
- readme 작성해야 하는 이유
- styled component GlobalStyle 사용방법
- Warning: Each child in a list should have a unique "key" prop.
- axios CRUD
- readme 이미지 추가 방법
- readme 작성 방법
- axios 설치하기
- styled component 사용방법
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |