공부블로그

Confirm 모달창 만들기 본문

자바스크립트

Confirm 모달창 만들기

떠어영 2022. 12. 12. 10:51

1. window에서 제공하는 window.confirm기능 사용

const onClickConfirm = () => {
        if(window.confirm('삭제하시겠습니까?')){
            alert('ok')
        }else{
            alert('cancel')
        }
    }

장점 : 진짜 간단하다

단점 : 커스텀이 안된다 (내가 알기로는) = 이쁘지가 않다

 

 

2. createPortal로 모달창 구현하기 

portal = 컴포넌트를 부모 컴포넌트 바깥에 렌더링해주는 것

1. public / index.html 에 Modal이 렌더링 될 위치 심어주기 

<body>
  <noscript>You need to enable JavaScript to run this app.</noscript>
  <div id="root"></div> //modal의 부모 컴포넌트
</body>

portal을 구현할 tree의 부모 컴포넌트를 어디로 설정할지 정하는 것

따로 만들어도 되고 나는 그냥 'root'에 구현할거라서 코드를 수정하지는 않았다.

 

2. ModalContainer.tsx 만들기

interface Props {
    children : React.ReactNode
}
const ModalContainer: React.FC<Props> = ({children}: Props) => {
    return createPortal(children, document.getElementById('root') as HTMLElement)
}
export default ModalContainer;

'react-dom'의 createPortal을 사용하여 포탈역할을 해주는 ModalContainer를 만들어준다.

첫번째 인자는 포탈을 통해 띄울 자식 컴포넌트를, 두번째 인자는 부모컴포넌트를 넣어준다.

 

3. Modal.tsx 만들기

const ModalWrapper = styled.div`
  position: absolute;
  top: 0;
  left: 0;
  height: 100%; /*100%*/
  width: 100%; /*100%*/
  display: flex;
  justify-content: center; //중앙 정렬
  align-items: center;
`
const Content = styled.div`
  box-sizing: border-box;
  position: fixed;
  width: 500px;
  height: 300px;
  background-image: linear-gradient(to top, #feada6 0%, #f5efef 100%);
  padding: 100px;
  text-align: center;
  border-radius: 50px;
`
const ButtonWrapper = styled.div`
  padding: 40px;
  display: flex;
  justify-content: space-around;
`
const ConfirmBtn = styled.button`
  border: none;
  border-radius: 10px;
  width: 70px;
  height: 50px;
  cursor: pointer;
  
  :hover{
    box-shadow: 3px 3px 3px lightcoral;
  }
`
export interface Props {
    id : number,
    setModalVisible : (val : boolean) => void
}
const Modal = ({ id, setModalVisible} : Props) => {

    const dispatch = useAppDispatch();
    const onClickConfirm = (id: number) => {
        dispatch(deleteTodoThunk(id))
        setModalVisible(false)
    }
     return(
            <ModalWrapper>
                <Content>
                    게시물을 삭제하시겠습니까?
                    <ButtonWrapper>
                        <ConfirmBtn onClick={() => setModalVisible(false)}>
                            취소
                        </ConfirmBtn>
                        <ConfirmBtn onClick={() => onClickConfirm(id) }>
                            확인
                        </ConfirmBtn>
                    </ButtonWrapper>
                </Content>
            </ModalWrapper>
     )
}
export default Modal

포탈을 통해 렌더링해줄 모달창을 만들어준다.

이 때 ModalWrapper는 모달창의 뒷배경으로 모달의 위치를 설정해주기 위해 보통 화면 전체로 설정한다. 

실제 우리가 보게되는 모달창은 <Content>컴포넌트이다.

 

4. 모달을 띄울 컴포넌트에 ModalContainer 조건부 렌더링

( App.tsx )

<ModalContainer>
        {modalVisible && <Modal id={deleteItem} setModalVisible={setModalVisible}/>}
</ModalContainer>

만들어 놓은 모달 컨테이너를 modalVisible state에 따라 조건적으로 렌더링 되도록 만들어준다.

 

모달창이 뜨게 되는 과정을 정리해보면, 

  1. 버튼을 누르면 modalVisible이 true로 변경
  2. ModalContainer에서 children을 root컴포넌트 바깥에 렌더링 (Portal을 만들어줌)
  3. children인자로 넘겨준 { modalVisible && <Modal> }가 포털에서 렌더링 → 모달 창 팝업

완성~!

 

[ 참고 사이트 ]
https://dev-bomdong.tistory.com/21
 

React | Portal을 이용한 Modal 구현

한국인에게 portal이란.. 닥터스트레인지의 마법진같은 포탈만 떠오를 수 있다. 이미 충분히 익숙한 다른 곳으로 이동시킨다는 개념을 이어받아, 컴포넌트를 부모 컴포넌트의 바깥에 렌더링해주

dev-bomdong.tistory.com

'자바스크립트' 카테고리의 다른 글

구조분해할당  (0) 2023.02.22
자바스크립트 중급강좌 #1- 코딩앙마  (0) 2022.04.03