-
Notifications
You must be signed in to change notification settings - Fork 1
컴포넌트 재사용성을 높여보자: Modal 분리기
Soobeen Yoon edited this page Dec 15, 2022
·
8 revisions
- 신규 todo 추가 및 수정까지 모두 담당하는 슈퍼 컴포넌트!
- 수정, 추가, validation check 등 수많은 로직들과 자식 컴포넌트들, 스타일까지 모두 가지고 있음.
- 컴포넌트 단위의 개발의 목적인 재사용성, 관심사의 분리, 응집도 있는 로직, 변경에 대한 유연성이 모두 어려워지고, table 외 다른 페이지에서 사용하기 어려워짐
컴포넌트는 사용자와의 인터렉션을 통해 필요한 비즈니스 로직을 실행하거나 스타일, 애니메이션과 같은 시각적인 부분을 표현하는 UI(User Interface)를 적절하게 나눈 것
- TableModal은 비즈니스 로직, 스타일, UI 모두 들어있다..
- validation check, save, create, edit, style 모두 들어있는 구조로,
컴포넌트 단위의 개발
이라는 철학에 부합하지 않음.
매우 많은 컴포넌트를 수정해야 하는 경우, 또는 해당 변경 사항이 생겼을 때 어떤 컴포넌트를 수정해야 하는지 분명하게 알 수 없는 경우 의존성 관리를 해야 한다.
- 불행하게도 TableModal은 재사용이 어려울뿐만 아니라, 새로운 input이 생겼을 때 수정하는 부분에 대한 부담도 커져버렸다.
- 또한 table 외의 다른 페이지에서 사용이 복잡해졌고, 새로운 형태의 Modal 개발 시 처음부터 Modal을 선언해야 하는 문제가 생겼다.
- TableModal을 EditModal, CreateModal로 분리하여 불필요한 분기를 없앰.
- 기존에는 Edit, Create를 한 컴포넌트에서 수행했기 때문에 로직 중에
if
로 분기하는 부분이 매우 많았음. - 단적인 예로, 부끄럽지만 기존 modal에서는 modalType에 따라 제목을 분기하여 처리하는 useEffect를 사용했는데, 타입별 분리를 통해 제목을 props로 전환할 수 있었다.
- 기존에는 Edit, Create를 한 컴포넌트에서 수행했기 때문에 로직 중에
useEffect(() => {
if (modalType === create) {
return setModalHeader('할 일 추가하기');
}
if (modalType === update) {
setInitData();
return setModalHeader('할 일 수정하기');
}
setModalHeader(none);
}, [modalType]);
- 이러한 EditModal, CreateModal의 상위에 모달이라면 꼭 필요한 기능들을
<Modal>
로 분리했다.- Style, Overlay 및 버튼 클릭 이벤트들
의존성 관리의 가장 큰 줄기는 불필요한 의존성을 제거하거나 약화시키고, 불가피하게 강하게 의존되는 요소들은 가깝게 두는 것에 있다.
- Modal은 Overlay와 강하게 의존이 필요하기 때문에, Modal Component 안에 Overlay 컴포넌트를 넣음으로써, 결합을 강화시켰다.
const Modal = ({ modalHeader, action, setIsModalOpen, children }: ModalProps): ReactElement => {
const modalWrapper = useRef();
// 생략
return (
<OverLay setHasModal={setIsModalOpen}>
<Wrapper ref={modalWrapper}>
// 생략
</Wrapper>
</OverLay>
);
};
export default memo(Modal);
- 먼저, validation check 등 컴포넌트 내부에 없어도 되는 로직을 util 파일로 분리했다.
- 컴포넌트에서 Todo 변경 시 update를 위해 수행하던 로직을 Custom Hook (
useModalComplete.ts
)로 분리했다. - 이에 따라, CreateModal, EditModal은 Modal에
action
을 전달하여 각각의 역할에 맞는 submit action을 수행할 수 있도록 하였다. - 아래는 CreateModal을 간략화한 예시이다.
const CreateModal = () => {
const [setComplete] = useModalComplete(MODAL_CREATE);
return (
<CreateModal>
<Modal action={setComplete} />
</CreateModal>
)
};
- 하나의 파일이 총 5개의 파일로 분리되어 모달 로직, 비즈니스 로직, 스타일으로 나누어 분리하게 됨.
- Modal이라는 공용 컴포넌트를 만든 덕분에 추상화, 분리, 재사용 등 측면에서 많은 것을 배울 수 있었다.
- 다만, 비즈니스 로직 자체, 특히 validation check하는 부분은 edit과 create가 여전히 같이 사용하고 완전히 분리해내지 못해서 이를 함수 단위로 쪼개면 더 좋을 것 같다는 피드백을 받았다.!!
- OaO 환경설정 A to Z
- CRLF 너가 뭔데 날 힘들게 해?
- Github Issue 똑똑하게 사용하기
- OAO! CI CD 적용기 with release 자동화
- 매번 다른 import문
- 못생긴 상대경로에서 간zlzl존 절대경로로😎
- TodoList API 개발기
- 의존성 주입으로 DB를 바꿔보자
- 렌더링 최적화 서막: useNavigate를 추가한 순간 리렌더 범위가 확장된 건에 대하여
- 렌더링 최적화 1탄: 렌더링 범위에 대하여 (by 최적화무새)
- 렌더링 최적화 2탄: 잘못된 custom hook 사용,, 전체 리렌더링을 부르다,,
- 렌더링 최적화 3탄: Todo 상세 좀 봤다고 테이블 전체가 재렌더링 되는건을 고치기😌
- 렌더링 최적화 4탄: 다이어그램 편
- 🐁 마우스 상대위치 계산은 이상해
- React 컴포넌트에 애니메이션을 적용해보자 🏃🏻💨
- 컴포넌트 재사용성을 높여보자: Modal 분리기 🌹
- 선후관계를 자동완성으로 추가해보자 🔎