[react] React Portal로 Modal 만드는 방법

dev stefanCho·2021년 7월 13일
0

react

목록 보기
6/19
post-custom-banner

Stacking context로 인한 이유로, React에서는 ReactDOM.createPortal로 Modal을 만들도록 한다.

createPortal은 리액트 공식문서에도 확인할 수 있다.

ReactDOM.createPortal(child, container)

위의 2번째 parameter에는 document.querySelector를 넣어준다. 이때 #root에 하는 것이 아니라, 새로운 id(예제에서는 #modal)을 새로 만들어서 그 아래에 랜더링 되도록 해준다.
(body 바로 밑에 랜더링하게 되면 Portal이 기존에 있던 DOM들을 다 덮어씌울수도 있기 때문이다.)

따라서 index.htmlid="modal"을 추가해주도록 한다.

<div id="root"></div>
<div id="modal"></div>

Modal Component는 아래처럼 만들 수 있다.
(semantic-ui를 사용했다.)

특징

  • Modal의 바깥을 클릭했을 때, 상위 컴포넌트의 onDismiss를 실행하도록 한다. (onDismiss는 url을 push하여, Modal이 사라지도록 한다.)
  • e.stopPropagation으로 Modal내부를 Click 했을 때는, onDismiss가 실행되지 않도록 한다.
    (onDismiss가 있는 event handler까지 올라가지 bubble up 되지 않도록 하는 것)
import React from 'react';
import ReactDOM from 'react-dom';

const Modal = (props) => {
  return ReactDOM.createPortal(
    <div className="ui dimmer active" onClick={() => props.onDismiss()}>
      <div className="ui modal standard active" onClick={(e) => e.stopPropagation()}>
        <div className="header">{props.title}</div>
        <div className="content">{props.content}</div>
        <div className="actions">{props.actions}</div>
      </div>
    </div>
    , document.querySelector('#modal')
  );
}

export default Modal;

Modal의 사용 예시이다. (ant design의 Modal과 상당히 유사한데, 코드 스타일을 대체적으로 이렇게 작성하는 듯 하다.)

render() {
    return (
      <div>
        <Modal
          title="Delete Stream"
          content="Do you want to delete this stream?"
          actions={this.renderActions()}
          onDismiss={() => history.push('/')}
        >
        </Modal>
      </div>
    )
  }
profile
Front-end Developer
post-custom-banner

0개의 댓글