React

[React] 모달 구현 및 모달 오픈 시 외부(배경) 스크롤 막기

dev_seon 2022. 12. 16. 15:31

프로젝트를 진행하며 글 상세 페이지를 모달로 구현하게 되었습니다.

기존에 구현해보았던 로그인 모달과는 달리 글 상세 페이지는 글 및 댓글의 내용의 길이에 따라 Modal 내부 영역의 height가 달라지게 되었습니다.

 

모달 오픈 시 필요에 따라 모달에 스크롤을 적용해야 했기 때문에 CSS의 overflow 속성을 활용하여 이를 구현하고자 했습니다.

처음에는 모달 Wrapper 영역의 overflow-y 속성만 auto 또는 scroll을 적용하면 될 것으로 생각하였으나, 해당 코드만을 추가할 경우 모달 외부 화면의 스크롤과 모달 Wrapper 영역의 스크롤이 이중으로 생성되는 문제가 발생했습니다.

 

때문에 모달 오픈 시 body 영역의 overflow를 hidden으로 설정하고, 모달을 닫을 때에는 body 영역의 overflow를 초기화 시켜주는 코드를 추가했고, 이를 해결할 수 있었습니다.

 

// index.tsx
const Community = () => {
  const [isModalOpened, setIsModalOpened] = useState(false);

  return (
    <CommunityContainer isModalOpened={isModalOpened}>
      {isModalOpened && <Modal setIsModalOpened={setIsModalOpened} />}
    </CommunityContainer>
  );
};

export default Community;
// Modal.tsx
const Modal = ({ setIsModalOpened }: ModalProps) => {
  const wrapperRef = useRef(null);

  const handleWrapperClick = (e: React.MouseEvent<HTMLDivElement>) => {
    if (wrapperRef.current === e.target) {
      setIsModalOpened(false);
      document.body.style.overflow = "unset";
    }
  };

  return (
    <ModalWrapper ref={wrapperRef} onClick={handleWrapperClick}>
      <ModalContainer>
        <button
          onClick={() => {
            setIsModalOpened(false);
            document.body.style.overflow = "unset";
          }}
        >
          <Image src={CloseImg} alt="close" />
        </button>
      </ModalContainer>
    </ModalWrapper>
  );
};

export default Modal;

const ModalWrapper = styled.div`
  position: fixed;
  width: 100%;
  height: 100%;
  left: 0;
  top: 0;
  background-color: rgba(0, 0, 0, 0.5);
  z-index: 20;
  overflow-y: auto;
`;

 

 

참고자료

- React: Prevent scroll when modal is open