Custom Modal Hook

์ด์žฌ์ง„ยท2023๋…„ 10์›” 12์ผ
0

๋ชจ์• ํ”„๋กœ์ ํŠธ

๋ชฉ๋ก ๋ณด๊ธฐ
3/16

useModal

๐Ÿคœ ๊ธฐ์กด์˜ Modal Component

๐Ÿ‘‰ modal component์„ ์–ธ

import React, { PropsWithChildren } from 'react';
import styled from 'styled-components';

interface ModalDefaultType {
  onClickToggleModal: () => void;
}

function Modal({
  onClickToggleModal,
  children,
}: PropsWithChildren<ModalDefaultType>) {
  return (
    <ModalContainer>
      <DialogBox>{children}</DialogBox>
      <Backdrop
        onClick={(e: React.MouseEvent) => {
          e.preventDefault();

          if (onClickToggleModal) {
            onClickToggleModal();
          }
        }}
      />
    </ModalContainer>
  );
}

const ModalContainer = styled.div`
  width: 300px;
  height: auto;
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
`;

const DialogBox = styled.dialog`
  display: flex;
  flex-direction: column;
  align-items: center;
  border: none;
  border-radius: 3px;
  box-shadow: 0 0 30px rgba(30, 30, 30, 0.185);
  box-sizing: border-box;
  background-color: white;
  z-index: 10000;
`;

const Backdrop = styled.div`
  width: 10000px;
  height: 10000px;
  position: fixed;
  top: 0;
  z-index: 9999;
  background-color: rgba(0, 0, 0, 0.2);
`;

export default Modal;

๐Ÿ‘‰ modal-component ์‚ฌ์šฉ

const [isOpenModal, setOpenModal] = useState<boolean>(false);

const onClickToggleModal = useCallback(() => {
    setOpenModal(!isOpenModal);
  }, [isOpenModal]);

...

{isOpenModal && (
            <Modal onClickToggleModal={onClickToggleModal}>
              <div>๋ชจ๋‹ฌ์•ˆ์ชฝ๋ชจ์”</div>
            </Modal>
          )}
          <button onClick={onClickToggleModal}>
            <div>๋ชจ๋‹ฌ๋ฒ„ํŠผ<div/>
          </button>

๐Ÿ‘‰ ๊ธฐ์กด modal-component์˜ ๋ฌธ์ œ์ 

์‚ฌ์šฉํ•  ๋•Œ๋งˆ๋‹ค ์‚ฌ์šฉํ•˜๋Š” ๊ณณ์—์„œ ์ƒํƒœ๋ฅผ ์ •์˜ํ•ด์„œ ์‚ฌ์šฉํ•ด์•ผํ•œ๋‹ค๋Š” ๋ถˆํŽธํ•จ๋„ ์žˆ๊ณ ,
๋ชจ๋“  ๋ชจ๋‹ฌ์ด ๋ชจ๋‘ ๊ฐ™์€ ์Šคํƒ€์ผ์„ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— hook์œผ๋กœ ๋งŒ๋“ค์–ด์„œ ์‚ฌ์šฉํ•ด์•ผ ๊ฒ ๋‹ค๊ณ  ์ƒ๊ฐํ–ˆ์Œ

๐Ÿคœ Modal Hook

๐Ÿ‘‰ Modal Hook์„ ์–ธ

//useModal.ts
import { useCallback, useState } from 'react';

const useModal = () => {
  const [isOpenModal, setOpenModal] = useState<boolean>(false);

  const handleModal = useCallback(() => {
    setOpenModal(!isOpenModal);
  }, [isOpenModal]);

  return {
    isOpenModal,
    handleModal,
  };
};

export default useModal;

๐Ÿ‘‰ Modal Hook ์‚ฌ์šฉ

const { isOpenModal, handleModal } = useModal();
...
{isOpenModal && <div>๋ชจ๋‹ฌ์•ˆ์ชฝ๋ชจ์”.</div>}
 <button onClick={handleModal}>๋ฒ„ํŠผ</button>

๋ชจ๋‹ฌ์„ ๋„์šธ ๋•Œ๋Š” ์ƒํƒœ๊ฐ€ ์ž˜ ๋ณ€๊ฒฝ์ด ๋˜์—ˆ์ง€๋งŒ, z-index๋กœ ๊ตฌํ˜„์„ ํ–ˆ์„ ๋•Œ, ๊ธฐ์กด ๋ฒ„ํŠผ์„ ๋ˆ„๋ฅด์ง€ ๋ชปํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ƒํƒœ๋ฅผ ๋‹ค์‹œ ๋ณ€๊ฒฝ์‹œํ‚ค์ง€ ๋ชปํ•ด์„œ, ๋‹ซ๊ธฐ๋ฅผ ํ•  ์ˆ˜ ์—†์—ˆ๋‹ค.

๊ทธ๋ž˜์„œ ๋ชจ๋‹ฌ ๋‚ด๋ถ€์— ๋‹ซ๊ธฐ ๋ฒ„ํŠผ์„ ์ถ”๊ฐ€ํ•ด ์ฃผ์—ˆ๋‹ค.

const { isOpenModal, handleModal } = useModal();
...
{isOpenModal && 
(
 <div>
   <button onClick={handleModal}>๋‹ซ๊ธฐ</button>
   <div>๋ชจ๋‹ฌ ์•ˆ์ชฝ ๋ชจ์”</div>
 </div>
 )}
 <button onClick={handleModal}>๋ฒ„ํŠผ</button>

๋ชจ๋‹ฌ ๋‚ด๋ถ€์—์„œ๋„ handleModal์„ ํ†ตํ•ด์„œ state๋ฅผ ๊ด€๋ฆฌํ•ด ์คฌ๋‹ค.

๐Ÿ‘‰ Modal Common Component ๋งŒ๋“ค๊ธฐ

์ด๋Ÿฐ์‹์œผ๋กœ ๊ตฌํ˜„ํ–ˆ์„ ๋•Œ, ๋งค ๋ฒˆ ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋งŒ๋“ค์–ด์„œ ๊ทธ์— ๋งž๊ฒŒ props๋ฅผ ์ „๋‹ฌํ•ด ์ค˜์•ผํ•˜๋Š” ๋ถˆํŽธํ•จ์ด ์žˆ์—ˆ๋‹ค. modal์˜ container component๋ฅผ ๋งŒ๋“ค์–ด์„œ ๊ด€๋ฆฌํ•˜๋ ค๊ณ  ํ•œ๋‹ค.

profile
๋‚˜์˜ ๋‡Œ๋ฅผ Refactoring

0๊ฐœ์˜ ๋Œ“๊ธ€