Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor(CLAP-184): ModalContainer 리팩토링 #132

Merged
merged 3 commits into from
Aug 26, 2024
Merged

Conversation

DaeWon9
Copy link
Collaborator

@DaeWon9 DaeWon9 commented Aug 26, 2024

🔗 연관된 이슈


📗 작업 내용

ModalContext, ModalProvider 타입 지정 리팩토링

이슈 내용

  • ModalContext에서 사용하던 ModalState내부 인자의 any 사용 이슈
import { createContext, Dispatch, SetStateAction } from "react";

export interface ModalState {
  type: any;
  props?: any;
}

export const ModalStateContext = createContext<ModalState | null>(null);
export const ModalSetterContext = createContext<Dispatch<
  SetStateAction<ModalState>
> | null>(null);

변경 사항

  • any를 제거하고 제네릭을 사용하여 타입 안전성을 높이고 코드의 품질을 개선함.
import { createContext, Dispatch, SetStateAction } from "react";

export interface ModalState<T, P> {
  type: T;
  props?: P;
}

export const ModalStateContext = createContext<ModalState<
  unknown,
  unknown
> | null>(null);

export const ModalSetterContext = createContext<Dispatch<
  SetStateAction<ModalState<unknown, unknown>>
> | null>(null);

// ModalType 정의
export type ModalType =
  | "login"
  | "alert"
  | "pending"
  | "navigate"
  | "confirm"
  | "description";

// DefaultModalProps 정의
export interface DefaultModalProps {
  isOpen: boolean;
  onRequestClose: () => void;
}

// ModalComponentMap 인터페이스 정의
interface ModalComponentMap {
  login: React.FC<DefaultModalProps>;
  alert: React.FC<AlertModalProps>;
  pending: React.FC<DefaultModalProps>;
  navigate: React.FC<NavigateModalProps>;
  confirm: React.FC<ConfirmModalProps>;
  description: React.FC<DescriptionModalProps>;
}

// MODAL_COMPONENT_MAP 구현
const MODAL_COMPONENT_MAP: ModalComponentMap = {
  login: GoogleLoginModal,
  alert: AlertModal,
  pending: PendingModal,
  navigate: NavigateModal,
  confirm: ConfirmModal,
  description: DescriptionModal,
};

// ModalStateMap 정의
export interface ModalStateMap {
  login: DefaultModalProps;
  alert: AlertModalProps;
  pending: DefaultModalProps;
  navigate: NavigateModalProps;
  confirm: ConfirmModalProps;
  description: DescriptionModalProps;
}

// ModalState 제네릭 타입 정의
export interface ModalState<T extends ModalType> {
  type: T;
  props?: ModalStateMap[T];
}

// ModalContainer 컴포넌트 정의
export const ModalContainer = () => {
  const { closeModal } = useModal();
  const modalState = useContext(
    ModalStateContext,
  ) as ModalState<ModalType> | null;

  if (!modalState || !modalState.type) {
    return null;
  }

  // modalState의 type과 props를 구체적으로 타입 캐스팅
  const { type, props } = modalState;

  // ModalComponent를 동적으로 선택
  const ModalComponent = MODAL_COMPONENT_MAP[type] as React.FC<
    ModalStateMap[typeof type]
  >;

  if (!ModalComponent) {
    return null;
  }

  // modalProps 정의
  const modalProps = {
    ...props,
    isOpen: Boolean(modalState.type),
    onRequestClose: closeModal,
  } as ModalStateMap[typeof type]; // modalProps 타입 지정

  return createPortal(
    <ModalComponent {...modalProps} />,
    document.getElementById("modal") as HTMLElement,
  );
};


✏️ 리뷰어 멘션

@DaeWon9 DaeWon9 requested a review from thgee August 26, 2024 02:58
@DaeWon9 DaeWon9 self-assigned this Aug 26, 2024
Copy link

Visit the preview URL for this PR (updated for commit b9a338e):

https://watermelon-clap--pr132-refactor-clap-184-x2yc6bkq.web.app

(expires Mon, 02 Sep 2024 03:07:48 GMT)

🔥 via Firebase Hosting GitHub Action 🌎

Sign: de0a942c5b755c54117c0c98d9eeaa5a5c97c307

Copy link

Finish "service" deployment!

@DaeWon9 DaeWon9 merged commit cfbf7ac into main Aug 26, 2024
3 checks passed
@DaeWon9 DaeWon9 deleted the refactor/CLAP-184 branch August 26, 2024 03:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants