230705 Custom hooks으로 modal 만들기
Modal의 불편함
Modal을 열고 닫는 상태 관리를 위한 useState의 사용
return 문안에서 조건 연산자를 사용한 Modal 렌더링
'확인', '취소' 버튼을 눌렀을 때 실행할 함수를 각각 props로 넘겨야 한다
function App() {
const [isOpenModal, setOpenModal] = useState(false);
return (
<div className="App">
<Button onClick={() => setOpenModal(true)}>medium 버튼</Button>
{isOpenModal && createPortal(
<Modal
type="confirm"
closeFunc={() => setOpenModal(false)}
confirmFunc={() => console.log("Confirmed")}
>
버튼이 2개인 모달
</Modal>,document.body
)}
</div>
);
}
usePopup의 장점
return문에서 Modal을 매번 import하고 props를 넘길 필요가 없어 재사용이 쉽고, 코드가 간결해진다.
function App() {
const [openPopup] = usePopup()
const handleOpenModal = () => {
const confirm = await openPopup({
title:'모달',
contents: `모달 내용`
})
if(!confirm) return // 취소 버튼 클릭
console.log("Confirmed") // 확인 버튼 클릭
}
return (
<div className="App">
<Button onClick={handleOpenModal}>medium 버튼</Button>
</div>
);
}
usePopup 구현
createRoot를 사용하여 루트를 만들고 render 함수를 사용하여 렌더링
팝업이 닫힐 때는 unmount를 사용
Create-react-app에서 document.getElementById('root') 에 <App/>을 렌더링하듯이
id='popupContainer'인 div를 root로 만들어서 내부에 팝업 컴포넌트를 렌더링
https://react.dev/reference/react-dom/client/createRoot
const usePopup = () => {
const createContainer = useCallback(() => {
const container = document.getElementById("popupContainer")
if(container) return container
const containerDiv = document.createElement('div')
containerDiv.id = 'popupContainer'
document.body.appendChild(containerDiv)
return containerDiv
},[])
const openPopup = useCallback(({ title, contents }) => {
const root = createRoot(createContainer());
return new Promise((resolve) => {
const handleConfirm = () => {
root.unmount()
resolve(true);
};
const handleCancel = () => {
root.unmount()
resolve(false);
};
root.render(
<div>
<div className="popup-bg" onClick={handleCancel}></div>
<div className="popup">
<h2>{title}</h2>
<div>{contents}</div>
<div className="popup-btns">
<button onClick={handleConfirm}>확인</button>
<button onClick={handleCancel}>취소</button>
</div>
</div>
</div>)
});
},[createContainer]);
return [openPopup];
};
'내일배움캠프' 카테고리의 다른 글
230707 jwt 토큰을 통한 인증 (0) | 2023.07.07 |
---|---|
230706 firebase 좋아요 기능 만들기 (0) | 2023.07.07 |
230704 useLoading hooks로 Promise 사용하기 (0) | 2023.07.04 |
KPT - 여행 사진 & 후기글 공유 뉴스피드 플랫폼, 트래블로그(TRAVELOG) (0) | 2023.07.03 |
230702 내일배움캠프 7주차 WIL (0) | 2023.07.02 |