서비스를 개발하다보면, 빼놓을 수 없는게 바로 Overlay 요소 인데요.
여러분들은 리액트에서 Overlay 어떻게 다루고 계신가요?
Overlay를 코드의 품질을 높이며, 사용할 수 있는 방법을 공유 드리고자 합니다.
우선 Overlay가 무엇인지 모르는 분들이 계실 수 있으니, 짤막 하게 설명드릴게요.
Overlay는 기본 콘텐츠 위에 겹쳐서 나타나는 시각적 레이어를 의미해요. 주로 다음과 같이 사용돼요.
아마 일반적으로 이런 형태로 작성하실 것 같아요.
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) 접근 방식이라고도 불러요. useState를 사용한 상태 관리와 이벤트 핸들링 코드가 섞여 있어 코드가 복잡하고 유지보수하기 어려웠죠.
상태관리 코드는 제거 하고, 응집도를 더 높여 코드를 보다 선언적으로 작성할 방법은 없을까요?
할 수 있습니다!
overlay-kit는 토스에서 만든 오픈소스인데요.
overlay를 보다 선언적으로 작성할 수 있게 만든 라이브러리에요.
overlay-kit은 특정 UI 라이브러리에 종속적이지 않으며 React 기반의 모든 UI 라이브러리와 호환돼요.
바로 코드를 보고 비교해볼까요?
import { overlay } from 'overlay-kit';
function MyPage() {
/* Other Hook calls... */
return (
<>
{/* Other components... */}
<Button
onClick={() => {
overlay.open(({ isOpen, close }) => {
return <Dialog open={isOpen} onClose={close} />;
});
}}
>
Open
</Button>
</>
);
}
수많은 보일러플레이트 코드도 사라지고, 오버레이 상태를 관리할 필요도 없어졌어요.
심지어 리액트바깥에서도 열 수 있어요.
예를 들어, API 호출 중 오류가 발생했을 때 오버레이를 띄워 사용자에게 알릴 수 있어요.
import ky from 'ky';
import { overlay } from 'overlay-kit';
const api = ky.extend({
hooks: {
afterResponse: [
(_, __, response) => {
console.log('test:: response', response);
if (response.status >= 400) {
overlay.open(({ isOpen, close }) => <ErrorDialog open={isOpen} onClose={close} />);
}
},
],
},
});
https://github.com/toss/overlay-kit?tab=readme-ov-file
overlay-kit는 어떤 철학을 가지고 태어난 친구인지 문서에서 자세히 볼 수 있어요!
도움이 되었다면, star (스댓구알..)와 많은 기여 부탁 드립니다!