회사 업무 도중 간단한 기능이 있는 관리자 페이지에서
confirm 함수를 통해서 기능을 구현하고 있었다.
confirm 함수란? 아래 사진과 같이 취소 혹은 확인 버튼을 통해서
true, false를 리턴하는 함수이다 이를 통해서
리턴값으로 인해서 특정 기능을 실행 할 수 있다.
기존에는
const confirm = window.confirm("확인을 누르면 페이지를 이동합니다")
if(confirm) {
navigate("이동할 페이지")
}
이런식으로 사용 할 수 있다.
디자인은 썩 예쁘다고 할 수 없지만
관리자 사이트에서 빠르게 기능을 처리 할 수 있었다.
하지만 리눅스 os firefox 브라우저에서 confirm 함수가 작동을 하지 않는 것이었다.
그래서 결국 confirm 컴포넌트를 만들기로 했다.
순서
1. confirm은 컴포넌트를 열 수 있는 상태를 가지고 있어야한다.
2. confirm은 제목과 부제목을 가지고 있어야 한다.
3. confirm은 액션 후 상태를 변경해야한다.
ui는 material ui 라이브러리를 사용하였다.
const ConfirmContext = createContext();
export const useConfirm = () => useContext(ConfirmContext);
export const ConfirmProvider = ({ children }) => {
const [isOpen, setIsOpen] = useState(false);
const [body, setBody] = useState({
title: '',
description: '',
icon: '',
color: ''
});
const [onConfirm, setOnConfirm] = useState(() => () => {});
const showConfirm = (obj, onConfirmAction) => {
setBody(obj);
setOnConfirm(() => onConfirmAction);
setIsOpen(true);
};
const hideConfirm = () => {
setIsOpen(false);
setOnConfirm()
};
const confirmAction = () => {
onConfirm();
hideConfirm();
};
return (
<ModalContext.Provider value={{ showConfirm, hideConfirm, confirmAction }}>
{children}
<Dialog
open={isOpen}
onClose={hideModal}
aria-labelledby="alert-dialog-title"
aria-describedby="alert-dialog-description"
fullWidth
maxWidth="sm"
>
<DialogTitle sx={{
textAlign: 'center',
margin: 0
}}><FontAwesomeIcon icon={body.icon}/></DialogTitle>
<DialogTitle id="alert-dialog-title" sx={{
textAlign: 'center'
}}>{body.title}</DialogTitle>
<DialogContent>
<DialogContentText id="alert-dialog-description" sx={{
textAlign: 'center',
color: body.color
}}>
{body.description}
</DialogContentText>
</DialogContent>
<DialogActions>
<Button onClick={hideConfirm} color="primary">
취소
</Button>
<Button onClick={confirmAction} color="primary" autoFocus>
확인하기
</Button>
</DialogActions>
</Dialog>
</ModalContext.Provider>
);
};
완성한
Confirm Provider는 전역상태에서 관리하기 때문에 provider로 컴포넌트를 감싸준다.
export default function App() {
return (
<ConfirmProvider>
<MqttProvider>
<BrowserRouter>
<ThemeProvider >
<Router />
</ThemeProvider>
</BrowserRouter>
</MqttProvider>
</ConfirmProvider>
);
}
const [onConfirm, setOnConfirm] = useState(() => () => {});
해당 코드부분인데 함수를 반환하는 형태로 callback함수처럼 사용하기 위해서 이렇게 지정했다.
const showConfirm = (obj, onConfirmAction) => {
setBody(obj);
setOnConfirm(() => onConfirmAction);
setIsOpen(true);
};
함수를 통해서 모달을 오픈할때 콜백함수를 넘겨받고 해당 callback함수는 onConfirm값에 저장된다.
저장된 onConfirm값을 통해서 확인 버튼에 클릭함수로 지정하면 confrim의 기능대신 action을 처리할 수 있다.
const { showConfirm } = useConfirm()
<DeleteButton
text={'삭제하기'}
actionFunction={() => {
showConfirm({
title: '삭제하기',
description: '삭제하시겠습니까?',
icon : faTrash},
handleDelete)}} />
window confirm 함수보다 깔끔한 화면을 디자인을 볼 수 있다!