[React] 공통 팝업 (모달) 만들기

빛나경·2022년 12월 7일
1

react

목록 보기
1/1

프로젝트 진행 중, 로그인 후에 에러 메세지를 보여줄 모달창이 필요해졌다.
다른 프로젝트에서도 최대한 재사용이 가능하도록 만들어 보기로 했다.

우선 관련된 모든 파일은 한 폴더 내에서 작업하기로 함!

폴더구조

메인파일 : PopupJs.js
상세팝업종류 : component > PopupType.js
스타일 : style.js (styled-components)
hook : hook > usePopup.js (팝업 열기,닫기)
recoil : state > popupState.js

사용법

  1. index.js 나 App.js 등 최상단 파일에서 PopupJs.js 컴포넌트를 넣어준다.
  1. 팝업이 필요한 파일에서 hook을 불러온다.
  1. 팝업창이 열리도록 addPopup() 함수에 속성 정보를 넘겨준다.

    ✨중요 : type에 따라 팝업 종류 결정
  1. type에 따라 해당 팝업 스타일 컴포넌트를 리턴한다. (중첩 팝업 가능)
    const filterPopup = (props, index) => {
        const {
            data: { type },
        } = props;
        if (type === 'basic') {
            return <BasicPopup key={index} {...props} />;
        }
        if (type === 'towBtn') {
            return <TowBtnPopup key={index} {...props} />;
        }
        if (type === 'fileUpload') {
            return <FileUploadPopup key={index} {...props} />;
        }
        if (type === 'fileExport') {
            return <FileExportPopup key={index} {...props} />;
        }
        if (type === 'boringAdd') {
            return <BoringAddPopup key={index} {...props} />;
        }
        return;
    };
    return <>{popupList.map((props, index) => filterPopup(props, index))}</>;
}
export default PopupJs;
  1. 대표적으로 <BasicPopup /> 형태
// 기본 팝업 - 단순 창 닫기
export function BasicPopup({ data: { title = '알림', text = '', confirm } }) {
    const { removeCurrentPopup } = usePopup();
    return (
        <Style.Dimmed>
            <Style.Wrap>
                <Style.Box>
                    <div className="title">
                        {title}
                        <button className="closeBtn" onClick={removeCurrentPopup}></button>
                    </div>
                    <div className="border"></div>
                    <div className="message">{text}</div>
                    <div className="btnWrap">
                        <button className="confirm" onClick={removeCurrentPopup}>
                            확인
                        </button>
                    </div>
                </Style.Box>
            </Style.Wrap>
        </Style.Dimmed>
    );
}
  1. hook > usePopup.js
export default function usePopup() {
    const [popupList, setPopupList] = useRecoilState(popupState);
    // 보여줄 팝업 추가 - 중첩 가능
    const addPopup = useCallback(({ key, data }) => {
        console.log('addpopup!');
        setPopupList((prev) => {
            let newModalList = [...prev];
            newModalList.push({ key, data }); // 추가
            return newModalList;
        });
    }, []);
    // 닫기 이벤트
    const removeCurrentPopup = useCallback(() => {
        console.log('removeCurrentPopup!');
        setPopupList((prev) => {
            let newModalList = [...prev];
            newModalList.pop(); // 마지막 항목 삭제
            return newModalList;
        });
    }, []);
    return {
        addPopup,
        removeCurrentPopup,
    };
}
profile
개발자로 살아가고 있습니다

0개의 댓글