모달 사용 컴포넌트에서 visible 상태를 관리하고 상태를 토글할 수 있는 함수를 관리합니다.
모달 컴포넌트는 visible 상태값, 상태를 토글할 수 있는 함수를 props로 받습니다.
단점: 모달을 사용할 때 마다 상태, 함수를 따로 관리해야된다.
모달 사용 컴포넌트는 ref를 관리
모달 컴포넌트는 useImperativeHandle과 ref를 통해서 모달안에서 visible 상태 관리를 함
장점: 독립적으로 모달이 상태를 관리하기 때문에 props로 넘겨줄 필요가 없음.
// 모달 사용 컴포넌트
import React, { useCallback } from 'react';
import KaKaoModal, { RefProps } from '@atoms/Modal/KaKaoModal';
const Index = (): React.ReactElement => {
const tempSaveRef = React.useRef<RefProps>(null);
const goToKakaoLogin = useCallback(() => {
console.log('카카오로그인으로 이동');
}, []);
const clickModal = useCallback(() => {
if (tempSaveRef.current) tempSaveRef.current.handleVisible();
}, []);
const onClickCancel = useCallback(() => {
console.log('모달 창 꺼짐과 동시에 실행');
}, []);
return (
<>
<button onClick={clickModal}>모달 열기</button>
<KaKaoModal ref={tempSaveRef} onClickOk={goToKakaoLogin} onClickCancel={onClickCancel} />
</>
);
};
export default Index;
// 모달
import React, { useState, forwardRef, useImperativeHandle, useCallback } from 'react';
import { ModalWrapper } from './KaKaoModal.styles';
interface Props {
onClickOk: () => void;
onClickCancel?: () => void;
}
export interface RefProps {
handleVisible: () => void;
}
const KaKaoModal = ({ onClickOk, onClickCancel }: Props, ref: React.Ref<RefProps>) => {
const [visible, setVisible] = useState(false);
const toggleVisible = useCallback(() => {
setVisible((prev) => {
if (!prev) return !prev;
if (onClickCancel) {
onClickCancel();
}
return !prev;
});
}, [onClickCancel]);
useImperativeHandle(ref, () => ({
handleVisible: () => toggleVisible(),
}));
return (
<ModalWrapper
visible={visible}
destroyOnClose
closable={false}
footer={null}
width={448}
centered
onCancel={toggleVisible}
>
<div onClick={toggleVisible}>취소</div>
<div onClick={onClickOk}>ok</div>
</ModalWrapper>
);
};
export default forwardRef(KaKaoModal);
// 모달 사용 컴포넌트
import React, { useCallback } from 'react';
import KaKaoModal, { RefProps } from '@atoms/Modal/KaKaoModal';
const Index = (): React.ReactElement => {
const tempSaveRef = React.useRef<RefProps>(null);
const goToKakaoLogin = useCallback(() => {
console.log('카카오로그인으로 이동');
}, []);
const clickModal = useCallback(() => {
if (tempSaveRef.current) tempSaveRef.current.handleVisible();
}, []);
return (
<>
<button onClick={clickModal}>모달 열기</button>
<KaKaoModal ref={tempSaveRef} onClickOk={goToKakaoLogin} />
</>
);
};
export default Index;
// 모달
import React, { useState, forwardRef, useImperativeHandle, useCallback } from 'react';
import { ModalWrapper } from './KaKaoModal.styles';
interface Props {
onClickOk: () => void;
}
export interface RefProps {
handleVisible: () => void;
}
const KaKaoModal = ({ onClickOk }: Props, ref: React.Ref<RefProps>) => {
const [visible, setVisible] = useState(false);
const toggleVisible = useCallback(() => {
setVisible((prev) => !prev);
}, []);
useImperativeHandle(ref, () => ({
handleVisible: () => toggleVisible(),
}));
return (
<ModalWrapper
visible={visible}
destroyOnClose
closable={false}
footer={null}
width={448}
centered
onCancel={toggleVisible}
>
<div onClick={toggleVisible}>취소</div>
<div onClick={onClickOk}>ok</div>
</ModalWrapper>
);
};
export default forwardRef(KaKaoModal);