Skip to content

πŸͺŸλͺ¨λ‹¬μ— κ΄€ν•˜μ—¬β€¦

gildong edited this page Nov 22, 2023 · 3 revisions

κ΅¬ν˜„μ™„λ£Œλœ λͺ¨μŠ΅

쀑첩λͺ¨λ‹¬

λͺ¨λ‹¬μ΄λž€ 무엇인가?

λͺ¨λ‹¬μ€ 이λͺ©μ„ μ§‘μ€‘μ‹œν‚€κΈ° μœ„ν•΄ μ‚¬μš©ν•˜λŠ” ν™”λ©΄ μ „ν™˜ 기법이닀.

ν”„λ‘ νŠΈμ—”λ“œμ—μ„œλŠ” λ°˜λ“œμ‹œ κ΅¬ν˜„ν•˜κ²Œ λ˜λŠ” 그것이닀.

곡톡 λͺ¨λ‹¬μ„ μœ„ν•˜μ—¬.

우리 μ„œλΉ„μŠ€λŠ” λͺ¨λ‹¬μ΄ ꡉμž₯히 λ§Žλ‹€.

λͺ¨λ‹¬μ΄ ν•˜λ‚˜λΏμ΄λΌλ©΄ λ”±νžˆ κ³ λ―Όν•˜μ§€ μ•Šκ² μ§€λ§Œ, 우리 μ„œλΉ„μŠ€λŠ” ꡉμž₯히 λͺ¨λ‹¬μ΄ λ§Žλ‹€.

Untitled Untitled2 Untitled3

λ°˜λ³΅ν•΄μ„œ μ‚¬μš©λ˜κΈ°μ— 곡톡 μ»΄ν¬λ„ŒνŠΈλ‘œ λ§Œλ“€μ–΄μ€„ ν•„μš”κ°€ μžˆμ—ˆλ‹€.

μ–΄λ–»κ²Œ κ΅¬ν˜„ν•  것인가?

λͺ¨λ‹¬μ„ κ΅¬μ„±ν•˜λŠ” 방법을 μ°Ύμ•„λ³΄λ‹ˆ μ—¬λŸ¬ 방법이 μžˆμ§€λ§Œ 크게 두 κ°€μ§€λ‘œ λΆ„λ₯˜λ˜λŠ” 것 κ°™μ•˜λ‹€.

1. λ£¨νŠΈμ— ν•˜λ‚˜λ§Œ μƒμ„±ν•˜μ—¬ μ „μ—­ μƒνƒœ(type, props)λ₯Ό λ³€κ²½ν•˜λ©° μž¬μ‚¬μš©

β‡’ 각 μ»΄ν¬λ„ŒνŠΈμ—μ„œ λͺ¨λ‹¬μ˜ μ „μ—­ μƒνƒœλ₯Ό λ³€κ²½ν•˜μ—¬ λ‚΄μš©μ„ λ°”κΎΈλŠ” λ“±μ˜ μž‘μ—…μ„ μˆ˜ν–‰

μž₯점

  1. root μš”μ†Œ 외에 DOMμš”μ†Œλ₯Ό μΆ”κ°€ν•˜μ—¬(usePortal ν™œμš©) 독립적인 modalꡬ성 κ°€λŠ₯
  2. Modalμ—μ„œλŠ” type에 따라 λͺ¨λ‹¬ λ‚΄μš©μ„ λ°”κΏ”μ£Όκ³ , modal 을 λ„μ›Œμ£ΌλŠ” μ»΄ν¬λ„ŒνŠΈλŠ” μ „μ—­ λͺ¨λ‹¬μ˜ typeκ³Ό propsλ§Œμ„ μ„€μ •ν•˜λ―€λ‘œ μ»΄ν¬λ„ŒνŠΈκ°„μ˜ μ—­ν• κ³Ό μ±…μž„μ΄ λͺ…확해짐

단점

  1. λͺ¨λ‹¬μ΄ ν•˜λ‚˜ μΆ”κ°€λ λ•Œλ§ˆλ‹€ Modalμ»΄ν¬λ„ŒνŠΈμ—μ„œ λͺ¨λ‹¬ type을 좔가해주어야함
  2. κ΅¬ν˜„μ΄ μ‰½μ§€μ•ŠμŒ

2. μ»΄ν¬λ„ŒνŠΈ ν•˜μœ„μ— λͺ¨λ‹¬μ„ μ‚½μž…ν•˜μ—¬ μ‚¬μš©

β‡’ λͺ¨λ‹¬ μ»΄ν¬λ„ŒνŠΈλŠ” ν…œν”Œλ¦Ώλ§Œμ„ μ œκ³΅ν•˜κ³ , 이λ₯Ό μ‚¬μš©ν•˜λŠ” μ»΄ν¬λ„ŒνŠΈμ—μ„œ μœ λ™μ μœΌλ‘œ μž‘μ„±ν•˜λŠ” ν˜•νƒœλ‘œ μž¬μ‚¬μš© ν•  수 μžˆλ„λ‘ ꡬ성

μž₯점

  1. modal은 root내뢀에 λ Œλ”λ§λ˜λ‚˜ , useModal을 톡해 Modal ν…œν”Œλ¦Ώμ„ κΊΌλ‚΄κ³ , Modal 의 λ‚΄λΆ€ μš”μ†ŒλŠ” modal을 λ„μš°λŠ” μ»΄ν¬λ„ŒνŠΈμ—μ„œ 결정해주기에 쑰금 더 μœ μ—°ν•˜κ³ , μ‚¬μš©ν•˜κΈ° 쉬움

단점

  1. μ „μ²΄μ˜ λͺ¨λ‹¬μ΄ μ–΄λ–€ 것듀이 μžˆλŠ”μ§€ νŒŒμ•…ν•˜κΈ° λͺ¨ν˜Έν•΄μ§
  2. μ»΄ν¬λ„ŒνŠΈμ˜ μ—­ν• κ³Ό μ±…μž„μ΄ λͺ¨ν˜Έν•΄μ§
  3. root내뢀에 λͺ¨λ‹¬μ΄ λ Œλ”λ§λ¨

μ–΄λ–»κ²Œ ν•΄κ²°ν–ˆλ‚˜? (nice-modal-react와 λͺ¨λ‹¬ λ°°μ—΄)

μ΄λ ‡κ²Œ κ³ λ―Όν•˜λ˜ 쀑 λ¦¬λ·°μ–΄λ‹˜κ»˜ 쑰언을 κ΅¬ν–ˆκ³ , λͺ¨λ‹¬μ΄ μ—¬λŸ¬κ°œ λœ¨λŠ” κ²½μš°κΉŒμ§€ κ³ λ €ν•΄λ³Όλ§Œν•˜λ‹€λŠ” 의견과 ν•¨κ»˜ 쒋은 라이브러리 μ½”λ“œ(https://github.com/eBay/nice-modal-react)λ₯Ό ν•˜λ‚˜ μ£Όμ…¨λ‹€.

ν•΄λ‹Ή 라이브러리의 μ½”λ“œλ₯Ό μ°Έκ³ ν•˜μ—¬ ν•΄κ²°ν•  수 μžˆμ—ˆλ‹€. useModal에 λͺ¨λ‹¬ 내뢀에 보일 μ»΄ν¬λ„ŒνŠΈλ₯Ό 인자둜 μ£Όκ³ , show, hideν•¨μˆ˜λ₯Ό μ–»μ–΄μ˜€λŠ” ν˜•νƒœλ‘œ κ΅¬ν˜„ν•΄μ£Όμ—ˆλ‹€.

이 λΌμ΄λΈŒλŸ¬λ¦¬λŠ” 기본적으둜 useContextλ₯Ό ν†΅ν•΄μ„œ μ²˜λ¦¬ν•˜κ³ μžˆμœΌλ‚˜, μš°λ¦¬λŠ” Zustandλ₯Ό 톡해 μ²˜λ¦¬ν•΄μ€„ 것이닀. 핡심 μ•„μ΄λ””μ–΄λŠ” λ°°μ—΄ ν˜•νƒœλ‘œ modal의 μƒνƒœλ₯Ό κ΄€λ¦¬ν•˜κ³  이걸 ν•„ν„°λ§ν•˜μ—¬ λ Œλ”λ§ν•˜λŠ” 것이닀.

λ˜ν•œ, λͺ¨λ‹¬λ‚΄λΆ€μ— λ“€μ–΄κ°ˆ μ»΄ν¬λ„ŒνŠΈλ₯Ό state둜 κ΄€λ¦¬ν•˜λ©΄ λ¬΄κ±°μš°λ―€λ‘œ, λͺ¨λ‹¬ μ»΄ν¬λ„ŒνŠΈμ˜ λ³Έμ²΄λŠ” λ”°λ‘œ 객체둜 κ΄€λ¦¬ν•œλ‹€.

export const MODAL_COMPONENTS: { [id: string]: { Comp: React.ComponentType<any>; props?: Record<string, unknown> } } = {};

type Modal = {
  id: string;
  visible: boolean;
  props: Record<string, unknown>;
};
type ModalState = {
  modals: Modal[];
  addModal: (id: string) => void;
  removeModal: (id: string) => void;
  showModal: (id: string) => void;
  hideModal: (id: string) => void;
};

그리고 이λ₯Ό modals μƒνƒœ 배열을 κ΄€λ¦¬ν•˜λŠ” actionν•¨μˆ˜ 4개λ₯Ό λ§Œλ“€μ–΄μ£Όμ—ˆλ‹€.

이λ₯Ό 톡해 이제 modals의 μƒνƒœ 배열을 관리할 수 있게 λ˜μ—ˆλ‹€. 이듀쀑 visible인 μ»΄ν¬λ„ŒνŠΈλ“€λ§Œ μ°μ–΄μ£Όλ©΄λœλ‹€.

export default function Modals() {
  const { modals } = useModalState((state) => state);
  const { hideModal } = useModalState((state) => state);
  const modalComponents = modals
    .filter((modal) => modal.visible) //visible인것 필터링
    .filter((modal) => MODAL_COMPONENTS[modal.id]) //modal λ°°μ—΄μžμ²΄μ—λŠ” μ»΄ν¬λ„ŒνŠΈκ°€ μ—†μœΌλ―€λ‘œ, MODAL_COMPONENTSμ—μ„œ κ°€μ Έμ˜΄
    .map((modal) => ({
      id: modal.id,
      Modal: MODAL_COMPONENTS[modal.id],
    }));

  return (
    <>
      {modalComponents.map(({ Modal, id }) => (
        <ModalWrapper cancel={() => hideModal(id)} key={id}>
          <Modal.Comp {...Modal.props} /> //κ°€μ Έμ˜¨ Modal배열을 λ Œλ”λ§ μ΄λ ‡κ²Œ ν•¨μœΌλ‘œμ¨ λͺ¨λ‹¬ μ—¬λŸ¬κ°œλ₯Ό ν•œλ²ˆμ— λ„μšΈ 수 μžˆκ²Œλœλ‹€.
        </ModalWrapper>
      ))}
    </>
  );
}

이제 μ΄λ ‡κ²Œ μ‚¬μš©ν•΄μ£Όλ©΄ λœλ‹€.

export default function ControllSection({ mediaObject }: { mediaObject: MediaObject }) {
  const { stream } = mediaObject;
  const { show } = useModal(SettingModal); //SettingModal의 PropsλŠ” showλ₯Ό 톡해 λ„˜κ²¨μ€€λ‹€.
  return (
    ...
      <button ... onClick={() => show({ mediaObject })}> //showμ—μ„œ propsλ₯Ό λ°›μ•„μ€€λ‹€.
         ...
      </button>
    </div>
  );
}

λͺ¨λ‹¬μ—μ„œ μžμ‹ μ„ λ‹«λŠ” 방법

μ΄λ ‡κ²Œ ν•˜λ‹ˆ λͺ¨λ‹¬μ΄ μžκΈ°μžμ‹ μ„ 찾을 수 μ—†λŠ”β€¦λ¬Έμ œκ°€ 생겼닀.

이 문제λ₯Ό ν•΄κ²°ν•˜κΈ° μœ„ν•΄ hideν•¨μˆ˜λ₯Ό 받아쀬닀.

export default function ControllSection({ mediaObject }: { mediaObject: MediaObject }) {
  const { stream } = mediaObject;
  const { show, hide } = useModal(SettingModal);

  return (
      ...
      <button
        type="button"
        className="w-[3vw] p-[1vw] hover:opacity-50 rounded-[15px] border-white"
        onClick={() => show({ mediaObject, hide })} //μ—¬κΈ°μ„œ λ°›μ•„μ£Όμ—ˆλ‹€.
      >
      ...

곡톡 λͺ¨λ‹¬ μ• λ‹ˆλ©”μ΄μ…˜ λ„μž…ν•˜κΈ°

λͺ¨λ‹¬μ„ μ—΄κ³  닫을 λ•Œ μ• λ‹ˆλ©”μ΄μ…˜μ„ μ£Όκ³  μ‹Άμ—ˆλ‹€.

μ–΄λ–»κ²Œ μ€„κΉŒ ν•˜λ‹€κ°€ μ΄λŸ°μ‹μœΌλ‘œ ν•΄κ²°ν–ˆλ‹€.

const ANIMATION_RENDER = 'relative p-4 bg-white rounded-2xl animate-render';
const ANIMATION_REMOVE = 'relative p-4 bg-white rounded-2xl animate-remove';

export default function Modal({ ... }: {
  Component: React.ComponentType<any>;
  modalProps?: Record<string, unknown>;
  hide: () => void;
}) {
  const [className, setClassName] = useState(ANIMATION_RENDER); 
  //μ• λ‹ˆλ©”μ΄μ…˜μ„ class이름을 λ³€κ²½ν•˜λŠ” ν˜•νƒœλ‘œ κ΅¬ν˜„
  ...
  const handleCancel = () => setClassName(ANIMATION_REMOVE); 
  //μ• λ‹ˆλ©”μ΄μ…˜μ„ μΌμœΌν‚΄
  const handleAnimationEnd = () => className === ANIMATION_REMOVE && hide(); 
  //μ• λ‹ˆλ©”μ΄μ…˜μ΄ λλ‚˜λ©΄ λͺ¨λ‹¬ μƒνƒœ λ³€κ²½
  const handleKeyDown = (e: React.KeyboardEvent) => e.key === 'Escape' && handleCancel(); //ESCλ₯Ό λˆ„λ₯΄λ©΄ λͺ¨λ‹¬ λ‹«κΈ°

  return (
    <div className="..." onClick={handleCancel}>
      <div
        ...
        className={className}
        onAnimationEnd={handleAnimationEnd}
        onKeyDown={handleKeyDown}
      >
       ...
        <div className="py-8 reative">
          <Component {...{ ...modalProps, hide: handleCancel }} /> 
          //handleCancel을 hideν•¨μˆ˜λ‘œ μ£Όμž…ν•œλ‹€.
        </div>
        ...
    </div>
  );
}

μ΄λ ‡κ²Œ μ£Όμž…λœ hideν•¨μˆ˜λŠ” Modal둜 쓰일 μ»΄ν¬λ„ŒνŠΈμ˜ hide둜 μ£Όμž…λ˜μ–΄, ν•΄λ‹Ή μ»΄ν¬λ„ŒνŠΈμ—μ„œ hideν•¨μˆ˜λ₯Ό ν˜ΈμΆœν•˜λ©΄ μ• λ‹ˆλ©”μ΄μ…˜μ„ νŠΈλ¦¬κ±°ν•˜κ³ , 이λ₯Ό 톡해 λͺ¨λ‹¬μ˜ μƒνƒœκ°€ λ³€κ²½λœλ‹€.

AlgoITNi

πŸ“• ν™ˆ
πŸ“• λ…Έμ…˜ λ³΄λŸ¬κ°€κΈ°
πŸ“• μ£Όμš” κΈ°λŠ₯

νŒ€

πŸ‘» 멀버
πŸ‘» κ·ΈλΌμš΄λ“œ λ£°
πŸ‘» μ»¨λ²€μ…˜
πŸ‘» 기술 정리
πŸ‘» μ œν’ˆ 백둜그 λ³΄λŸ¬κ°€κΈ°

회의둝

πŸ“„ week1
πŸ“„ week2
πŸ“„ week3
πŸ“„ week4
πŸ“„ week5
πŸ“„ week6

회고

🎞️ week1
🎞️ week2
🎞️ week3
🎞️ week4
🎞️ week5
🎞️ week6

Clone this wiki locally