728x90
반응형
React Bootstrap과 동일한 패턴을 작성하고 싶었다.
# 문제점
이전 컴포넌트의 구성은 ModalBody의 children을 제외한 Header[Title], Footer이 파라미터로 들어가 정해진 구성으로 들어가 일관성 있는 UI를 나타낼 수 있지만 다른 구성 및 스타일로 바꾸기 힘들고 하나의 컴포넌트가 많은 파라미터를 받아 해당 파라미터가 어디에 관련이 있는지 알기 어렵다.
<ModalTemplate
modalState={modalState}
handleClose={handleClose}
modalTitle="레이아웃 추가"
width="600px"
buttonList={[
<WhiteButton onClick={handleClose}>닫기</WhiteButton>,
<BlackButton onClick={insertLayout}>저장</BlackButton>,
]}
>
<div>모달입니다.</div>
</ModalTemplate>
장점
- 자유롭게 컴포넌트를 구성 및 스타일 변경이 가능하다.
- 서브 네임으로 구획을 정확히 나눌 수 있다.
- 서브 컴포넌트의 파라미터 배분으로 정갈한 코드를 작성할 수 있다.
단점
자유도가 높은 만큼 사용자가 컴포넌트 구성의 이해가 필요하고 예상하지 못한 동작이 일어날 가능성이 있다.
# Compound Component 구성
<Modal open={open} handleClose={() => setOpen(false)}>
<Modal.Header closeButton>모달헤더</Modal.Header>
<Modal.Body>모달입니다.</Modal.Body>
<Modal.Footer>
<WhiteButton onClick={handleClose}>닫기</WhiteButton>
<BlackButton onClick={insertLayout}>저장</BlackButton>
</Modal.Footer>
</Modal>
# Compound Component 코드
import styled from '@emotion/styled';
import { createContext, useContext } from 'react';
import { IoClose } from 'react-icons/io5';
import { createPortal } from 'react-dom';
const ModalContext = createContext(null);
const Modal = ({ open, handleClose, children }) => {
const contextValue = { open, handleClose };
return (
<ModalContext.Provider value={contextValue}>
{open &&
createPortal(
<ModalWrap>
<ModalBackDrop onClick={handleClose} />
<ModalContent>{children}</ModalContent>
</ModalWrap>,
document.body,
)}
</ModalContext.Provider>
);
};
const ModalHeader = ({ closeButton, children }) => {
const { handleClose } = useContext(ModalContext);
return (
<ModalHeaderWrap>
{children}
{closeButton && <IoClose onClick={handleClose} />}
</ModalHeaderWrap>
);
};
const ModalBody = ({ children }) => {
return <ModalBodyWrap>{children}</ModalBodyWrap>;
};
const ModalFooter = ({ children }) => {
return <ModalFooterWrap>{children}</ModalFooterWrap>;
};
//...Styled CSS 제거...
export default Object.assign(Modal, {
Header: ModalHeader,
Body: ModalBody,
Footer: ModalFooter,
});
728x90
반응형
'React' 카테고리의 다른 글
React 빌드 용량 최적화 - Vite rollupOptions manualChunks (0) | 2023.09.07 |
---|---|
Dynamic Import / Lazy Loading - 코드 스플리팅[Code Splitting] (0) | 2023.09.07 |
React createPortal(Modal Component) (0) | 2023.07.11 |
React Route dom v6 하위 경로 이동 시 에도 인덱스 NavLink 활성화 (0) | 2023.07.04 |
JEST-REACT18-Vite (0) | 2023.05.22 |