React 프로젝트에서 Dialog 상태를 관리하는 방법은 다양하다.
하지만 프로젝트가 커질수록 Dialog 상태와 로직이 상위 컴포넌트에 흩어져 관리가 어려워지는 문제가 발생한다.
useDialog
라는 Custom Hook을 만들어, Dialog 상태를 간결하고 재사용 가능하게 개선한 방법을 공유한다.
기존에는 각 Dialog마다 useState
를 상위 컴포넌트에서 선언하고, 상태를 직접 관리했다.
import { useState } from 'react';
import FormDrawer from '~/components/form/FormDrawer';
const ParentComponent = () => {
const [isDialogOpen, setDialogOpen] = useState(false);
const openDialog = () => setDialogOpen(true);
const closeDialog = () => setDialogOpen(false);
return (
<>
<button onClick={openDialog}>Open Dialog</button>
<FormDrawer open={isDialogOpen} onClose={closeDialog}>
<UserForm onClose={closeDialog} />
</FormDrawer>
</>
);
};
문제점
1. 반복적인 코드: Dialog마다 useState, openDialog, closeDialog를 선언해야 했다.
2. 상위 컴포넌트 복잡도 증가: 여러 Dialog를 관리할수록 상위 컴포넌트가 복잡해졌다.
3. 재사용성 부족: Dialog 상태 관리 로직이 분산되어 있어 재사용이 어려웠다.
이 문제를 해결하기 위해 useDialog
라는 Custom Hook을 도입했다.
useDialog
는 Dialog의 상태와 열림/닫힘 로직을 캡슐화하여, 상위 컴포넌트를 간결하게 유지했다.
// useDialog custom hook
import { useState, useCallback } from 'react';
import FormDrawer from '~/components/form/FormDrawer';
const useDialog = () => {
const [isOpen, setIsOpen] = useState(false);
const openDialog = useCallback(() => setIsOpen(true), []);
const closeDialog = useCallback(() => setIsOpen(false), []);
const Dialog = ({ children }: { children: React.ReactNode }) => (
<FormDrawer open={isOpen} onClose={closeDialog}>
{children}
</FormDrawer>
);
return { isOpen, openDialog, closeDialog, Dialog };
};
export default useDialog;
// Parent dialog
import { useDialog } from '~/hooks/useDialog';
const ParentComponent = () => {
const { openDialog, closeDialog, Dialog } = useDialog();
return (
<>
<button onClick={openDialog}>Open Dialog</button>
<Dialog>
<UserForm onClose={closeDialog} />
</Dialog>
</>
);
};
개선된 점
1. 간결한 코드: useDialog를 통해 Dialog 상태 관리 로직을 재사용 가능하게 만들었다.
2. 상위 컴포넌트 단순화: Dialog와 관련된 로직이 Custom Hook으로 이동하여, 상위 컴포넌트가 깔끔해졌다.
3. 확장성: 여러 Dialog를 동일한 방식으로 관리할 수 있어, 프로젝트 확장 시 유리하다.
useDialog
를 도입함으로써 Dialog 상태 관리가 훨씬 간단하고 효율적으로 변했다. 특히, 프로젝트가 커질수록 이런 Custom Hook을 활용한 상태 관리 방식이 코드의 가독성과 유지보수성을 높이는 데 큰 도움이 된다.
이 방식으로 Dialog뿐만 아니라 Modal, Toast 등 다른 UI 요소에도 응용할 수 있다.
기준 | 상위 컴포넌트에서 useState | Custom Hook 사용 |
---|---|---|
프로젝트 규모 | 상태 관리 로직이 간단하거나 소규모 프로젝트에서 적합 | 상태 관리 로직이 많거나 대규모 프로젝트에서 유리 |
재사용성 | 재사용이 필요하지 않다면 굳이 Custom Hook이 필요 없음 | 동일한 로직을 여러 곳에서 사용할 경우 적합 |
코드 복잡도 | 단순하고 직관적이지만 코드가 길어질 가능성 있음 | 추상화로 인해 복잡도가 증가할 수 있음 |
초기 구현 비용 | 바로 구현 가능 | 설계와 구현 시간이 더 걸림 |
유지보수성 | 중복된 로직이 많아질 경우 유지보수 비용 증가 | 상태 관리 로직이 분리되어 유지보수에 용이 |