리액트에서 Overlay를 다루는 갓벽한 5분컷 방법

Overlay ?

기본 콘텐츠 위에 겹쳐서 나타나는 시각적 레이어를 의미해요. 주로 다음과 같이 사용돼요.

  • 모달/팝업

  • 로딩 스피너

  • 툴팁/드롭다운 메뉴


여러분들은 실무에서 overlay를 어떻게 다루고 계신가요?


Overlay 요소를 사용할때, 일반적인 사용법

아래 코드는 많은 부분이 생략 됐지만,

일반적으로 overlay 요소를 사용할때는 아래와 같은 문제점이 있어요.

  1. 많은 보일러플레이트 코드가 필요해요.

  2. 리액트 훅의 규칙 때문에 상태 선언, 상태 변화, 렌더링 로직이 분리되어 코드 흐름을 파악하기가 어려워요.

  3. isOpen 상태 선언, onClick 상태 변화, 상태에 따라 렌더링되는 <Dialog /> 컴포넌트가 멀리 떨어져 있어요.

import { useState } from 'react';
 
function MyPage() {
  const [isOpen, setIsOpen] = useState(false);
  /* Other Hook calls... */
  return (
    <>
      {/* Other components... */}
      <Button
        onClick={() => {
          setIsOpen(true);
        }}
      >
        Open
      </Button>
      {/* Other components... */}
      <Dialog
        open={isOpen}
        onClose={() => {
          setIsOpen(false);
        }}
      />
    </>
  );
}


명령형(Imperative) 대신 Declarative Overlay Pattern 사용하기


Declarative Overlay Pattern는 오버레이를 상태가 아닌 동작(Behavior) 중심으로 관리해 더 직관적이고 선언적인 코드를 작성할 수 있도록 해요.


명령형 접근 방식

상태 관리와 이벤트 핸들링이 결합되어 중복 코드가 많고, 가독성이 떨어져요.

import { useState } from 'react';
 
function Overlay() {
  const [isOpen, setIsOpen] = useState(false);
 
  function handleOpen() {
    setIsOpen(true);
  }
 
  function handleClose() {
    setIsOpen(false);
  }
 
  return (
    <>
      <Button onClick={handleOpen}>열기</Button>
      <Dialog open={isOpen} onClose={handleClose}>
        <DialogTitle>명령형 오버레이</DialogTitle>
        <DialogActions>
          <Button onClick={handleClose}>확인</Button>
          <Button onClick={handleClose}>취소</Button>
        </DialogActions>
      </Dialog>
    </>
  );
}


선언적 접근 방식

상태 관리 코드를 제거하고, UI와 동작을 분리해 가독성과 유지보수성이 향상돼요.

import { overlay } from 'overlay-kit';
 
function Overlay() {
  return (
    <Button
      onClick={() => {
        overlay.open(({ isOpen, close }) => (
          <Dialog open={isOpen} onClose={close}>
            <DialogTitle>선언적 오버레이</DialogTitle>
            <DialogActions>
              <Button onClick={close}>확인</Button>
              <Button onClick={close}>취소</Button>
            </DialogActions>
          </Dialog>
        ));
      }}
    >
      열기
    </Button>
  );
}


바로 도입해보기

Overlay 요소를 보다 선언적 으로 사용하기 위해 toss/overlay-kit 라이브러리를 사용해봤어요.

이제 다시 코드를 보면, 구현체가 심플해지고, 응집도가 높아진 모습을 볼 수 있어요.


https://github.com/toss/overlay-kit?tab=readme-ov-file


import { overlay } from 'overlay-kit';
 
function MyPage() {
  return (
    <>
      <Button
        onClick={() => {
          overlay.open(({ isOpen, close }) => {
            return <Dialog open={isOpen} onClose={close} />;
          });
        }}
      >
        Open
      </Button>
    </>
  );
}


더 자세한 내용은 overlay-kit 문서에서 보실 수 있어요.


overlay-kit 으로 생각하기도 꼭 한번 읽어보세요!

https://overlay-kit.slash.page/ko/docs/guides/think-in-overlay-kit


멋진 여러분들의 star와 기여를 기다리고 있어요!

GitHub - toss/overlay-kit: A library for handling overlays more easily in React.

GitHub

GitHub - toss/overlay-kit: A library for handling overlays more easily in React.

다음 내용이 궁금하다면?

또는

이미 회원이신가요?

2025년 3월 23일 오전 10:54

댓글 0

    함께 읽은 게시물


    [선착순] Chat GPT, 후배들 활용법에 어깨너머 감탄만 하셨다면?

    5

    ... 더 보기

    하루 10분으로 부업부터 업무 자동화까지! 실전 GPT 배우기

    항해99

    하루 10분으로 부업부터 업무 자동화까지! 실전 GPT 배우기

    조회 78


    오픈 소스 라이선스 가이드

    ... 더 보기

    오픈 소스 라이선스 가이드

    www.daleseo.com

    오픈 소스 라이선스 가이드

     • 

    저장 25 • 조회 3,241



    🍆쿠팡과 컬리의 '농가 살리기'를 보면 기업의 정체성이 드러납니다

    ... 더 보기

    [인사이드 스토리]쿠팡과 컬리의 같은 듯 다른 '농가 살리기'

    비즈니스워치

    [인사이드 스토리]쿠팡과 컬리의 같은 듯 다른 '농가 살리기'