I want to render Modal.tsx
in MyInfoPage.tsx
(or anywhere I want to show modal).
So, I created simple custom hook useModal.ts
to control isOpenModal
.
But, I encountered some rendering problem.
When I try to close modal using closeModal()
in Modal.tsx
's backdrop div
tag, there is any change!
More clearly, setIsOpenModal(false)
in closeModal()
which implemented in useModal.ts
does not work...
Oddly, only setIsOpenModal
doesn't work! Other code like console.log()
does work!
I'm very confused about why only setIsOpenModal(false)
statement doesn't work.
What's wrong with this code? What concept am I confusing?
// MyInfoPage.tsx
// ...import... //
function MyInfoPage(props: MyInfoPageProps) {
// ... //
const { isOpenModal, openModal, closeModal } = useModal();
const cancelClickHandler = () => {
openModal();
};
const pageBackHandler = () => {
closeModal();
router.back();
};
return (
<section className={styles.section}>
{isOpenModal && (
<Modal>
<div>
<button onClick={pageBackHandler}>Yes</button>
<button onClick={closeModal}>No</button>
</div>
</Modal>
)}
// .... //
</section>
);
}
export default MyInfoPage;
// Modal.tsx
// ...import... //
function Modal(props: ModalProps) {
const { closeModal } = useModal();
const content = (
<>
<div className={styles.backdrop} onClick={closeModal}></div>
<div className={styles.modal_body}>
<div>{props.children}</div>
</div>
</>
);
return createPortal(content, document.getElementById("modal") as HTMLElement);
}
export default Modal;
// useModal.ts
// ...import... //
interface UseModalHook {
isOpenModal: boolean;
openModal: () => void;
closeModal: () => void;
}
function useModal(): UseModalHook {
const [isOpenModal, setIsOpenModal] = useState(false);
const openModal = () => {
setIsOpenModal(true);
};
const closeModal = () => {
setIsOpenModal(false);
};
return { isOpenModal, openModal, closeModal };
}
export default useModal;