hmk run dev

커스텀훅을 이용해 리액트 modal 깔끔하게 다루기 본문

Front-End

커스텀훅을 이용해 리액트 modal 깔끔하게 다루기

hmk run dev 2024. 10. 26. 11:55

현대의 React 개발에서는 훅이 상태와 부수 효과를 관리하는 강력한 도구로 자리 잡았습니다. 훅을 사용하면 컴포넌트 로직을 재사용 가능한 함수로 추출할 수 있어 코드가 모듈화되고 유지보수가 쉬워집니다. 이번 포스트에서는 useModal이라는 스텀 훅을 사용하여 React 컴포넌트를 어떻게 개선했는지에 대한 실제 사례를 소개합니다.

 
 

기존 접근 방식

 

useModal을 도입하기 전에는 포넌트 내에서 모달 로직을 직접 처리했습니다. 이 방식은 반복적인 코드가 많아지고, 애플리케이션의 여러 부분에서 모달 상태를 관리하기 어려워지는 문제가 있었습니다. 다음은 모달 로직이 어떻게 처리되었을지에 대한 간단한 예입니다:

// ... 기존 코드 ...
const [isModalOpen, setIsModalOpen] = useState(false);

const openModal = () => setIsModalOpen(true);
const closeModal = () => setIsModalOpen(false);

const handleLogClick = async (progressDetailId) => {
  // ... 기존 코드 ...
  if (logInfo) {
    setIsModalOpen(true);
  }
// ... 기존 코드 ...
};
// ... 기존 코드 ...
{isModalOpen && (
  <CustomerLogInfoModal
    open={isModalOpen}
    info={logInfo}
    onCancel={closeModal}
  />
)}
// ... 기존 코드 ...

 

 

문제점

 
1. 반복적인 코드: 모달이 필요한 각 컴포넌트가 자체적으로 상태와 핸들러를 관리해야 했습니다.
 
2. 복잡성: 애플리케이션이 커질수록 여러 모달을 관리하는 것이 번거롭고 오류가 발생하기 쉬웠습니다.
 

3. 재사용성 부족: 모달 로직이 컴포넌트에 강하게 결합되어 있어 다른 컴포넌트에서 재사용하기 어려웠습니다.

 

 

useModal을 활용한 개선된 접근 방식

useModal 훅을 도입함으로써 모달 로직을 재사용 가능한 함수로 캡슐화했습니다. 이는 코드 중복을 줄이고 컴포넌트의 가독성과 유지보수성을 향상시켰습니다.

 

 

useModal 훅

useModal 훅은 모달 상태를 추상화하고 모달을 열고 닫는 유틸리티 함수를 제공합니다. 다음은 구현 예시입니다:

 

 

useModal.tsx

interface ModalContextType {
  isModalOpen: boolean;
  modalContent: ReactNode | null;
  openModal: (content: ReactNode) => void;
  closeModal: () => void;
}

const ModalContext = createContext<ModalContextType | undefined>(undefined);

export const ModalProvider: React.FC<{ children: ReactNode }> = ({
  children,
}) => {
  const [isModalOpen, setIsModalOpen] = useState(false);
  const [modalContent, setModalContent] = useState<ReactNode | null>(null);

  const openModal = (content: ReactNode) => {
    setModalContent(content);
    setIsModalOpen(true);
  };

  const closeModal = () => {
    setIsModalOpen(false);
    setModalContent(null);
  };

  return (
    <ModalContext.Provider
      value={{ isModalOpen, modalContent, openModal, closeModal }}
    >
      {children}
    </ModalContext.Provider>
  );
};

export const useModal = (): ModalContextType => {
  const context = useContext(ModalContext);
  if (!context) {
    throw new Error('useModal must be used within a ModalProvider');
  }
  return context;
};

 

app.tsx

export default function App({ Component, pageProps }: AppProps) {

  return (
    <ErrorBoundary>
        <ModalProvider>
          ...기존 app.tsx jsx 구현부
        </ModalProvider>
    </ErrorBoundary>
  );
}

 

 

home.tsx (layout)

export default function Home() {
  const { isModalOpen, modalContent } = useModal();

  return (
    <div>
      <Head>
        <title>title</title>
      </Head>

   	  ...기존 코드
      
      {isModalOpen && modalContent}
    </div>
  );
}

 

 

useModal을 이용해 리팩토링된 컴포넌트

// ... 기존 코드 ...
const { openModal, closeModal } = useModal();

const handleLogClick = async (progressDetailId: number) => {
  // ... 기존 코드 ...
  if (logInfo) {
    openModal(
      <CustomerLogInfoModal
        open={true}
        info={{
          ...logInfo,
          userName: userInfo.name || '',
        }}
        onCancel={closeModal}
      />,
    );
  }
// ... 기존 코드 ...
};
// ... 기존 코드 ...

 

 

장점

1. 재사용성: useModal 훅은 다양한 컴포넌트에서 사용할 수 있어 코드 재사용을 촉진합니다.

 

2. 가독성: 모달 로직이 추상화되어 컴포넌트가 더 읽기 쉬워졌습니다.

 

3. 유지보수성: 모달 동작에 대한 변경 사항을 한 곳에서 관리할 수 있어 버그 발생 위험이 줄어듭니다.

 

 

결론

useModal과 같은 커스텀 훅을 활용하면 React 애플리케이션의 구조와 품질을 크게 향상시킬 수 있습니다. 이러한 접근 방식은 코드베이스를 더 유지보수하기 쉽게 만들고, 더 확장 가능한 애플리케이션을 구축할 수 있게 해줍니다. React 컴포넌트를 개선하고 싶다면 반복적인 로직을 커스텀 훅으로 추상화하는 것을 고려해보세요.

 

 

글을 통해 useModal 훅의 장점을  전달할  있기를 바랍니다. 필요에 따라 내용을 조정하거나 추가적인 기술적 세부사항을 포함시켜도 좋습니다!

Comments