useModal - 여러 개의 Modal중 동적으로 사용되는 모달 컴포넌트

miin·2024년 3월 1일
0

Skill Collection [Function]

목록 보기
44/46

모달이 너무 많아서 최대한 효율적으로 사용해보려고 나눠보긴 했는데 여전히 비효율적이고 의존성이 있는것 같다
이미지는 코드를 좀 더 이해하기 쉽게 직접 만들었다 예시가 이상함주의...

조금 더 고민해 보기로!

여기서 모두 사용되는 isOpen, setIsOpen은. setIsOpen을 호출하면 원래있던 값에서 반대로 바꿔주는 useHook이다
{isOpen && } 의 isOpen에 의존하지 않고 그냥 무조건 isOpen이 ture가 되면 실행된다

제일 기본 모달훅

<Modal isOpen={isOpen}>
      <ModalContainer onPress={() => setIsOpen(false)} justify={justify}>
        {children}
      </ModalContainer>
</Modal>

기본 모달훅을 이용해 헤더는 children으로 받고,
중간 아이콘 버튼은 동적으로 받게 구현했다

type SelectModalProps = {
  title: string;
  isOpen: boolean;
  setIsOpen: () => void;
  children?: React.ReactNode; //header
  modalData: {text: string; icon: React.ReactNode; onPress: () => void}[];
  btnText: string;
  btnOnPress: () => void;
};

const MultipleSelectModal = ({
  title,
  isOpen,
  setIsOpen,
  children,
  modalData,
  btnText,
  btnOnPress,
}: SelectModalProps) => {
  return (
    <ModalForm isOpen={isOpen} setIsOpen={setIsOpen}>
      <ShareModalContainer>
        {children}
        <div>
          <ModalTitle>{title}</ModalTitle>
        </div>
        <ItemContainer listLength={modalData.length}>
          {modalData.map(item => (
            <ButtonWrapper onChange={item.onPress}>
              {item.icon}
              <TypeText>{item.text}</TypeText>
            </ButtonWrapper>
          ))}
        </ItemContainer>

        <ConformBtn onChange={btnOnPress}>
          <BtnText>{btnText}</BtnText>
        </ConformBtn>
      </ShareModalContainer>
    </ModalForm>
  );
};

const ItemContainer = styled(FlexRow)<{listLength: number}>`
  gap: ${({listLength}) => (listLength < 4 ? '40%' : '25%')};
  padding: 0 7%;
  margin-bottom: 50px;
`;

헤더가 있는 모달 구현

   const modalData = [
    {
      text: '나시하기',
      icon: <Icon />,
      onPress: () => setBtnText({title: '나시하기', text: '완료'}),
    },
    {
      text: '구두하기',
      icon: <Icon />,
      onPress: () => setBtnText({title: '구두하기', text: '완료'}),
    },
  ];
  
  <MultipleSelectModal
          isOpen={isOpen}
          setIsOpen={() => setIsOpen()}
          modalData={modalData}
          btnText='닫기'
          title='Name'
          btnOnPress={conformBtnHandler}>
          <UserImageBox>
            <Image
              source={
                user.thumbnailPath === null
                ? sorce('~/assets/logo/ico_user_default_img.png')
                : {uri: user.thumbnailPath}
              }
            />
          </UserImageBox>
        </MultipleSelectModal>

헤더가 없고, title만 있는 모달 구현

  const [isOpen, setIsOpen] = useToggle(false);
     
   const modalData = [
    {text: '조명', icon: <CopyIcon />, onChange: copyToClipboard},
    {text: '반팔', icon: <KakaoIcon />, onChange: shareKakao},
    {text: '반바지', icon: <InstaIcon />, onChange: shareInstagram},
  ];
  
   <MultipleSelectModal
        title="공유하기"
        isOpen={isOpen}
        setIsOpen={setIsOpen}
        modalData={modalData}
        btnText="닫기"
        btnOnPress={() => setIsOpen()}
      />

0개의 댓글