실제 프로덕션 환경에서 컴포넌트를 만들다 보면, 여러 경우에 따라 다른 컴포넌트를 보여줘야 하는 경우가 많다.
예를 들어 파일 다운로드 관련하여 준비, 진행, 완료라는 세 가지 타입을 가진 데이터를 내려준다고 해보자.
export enum DownLoadStatus {
"ready" = "ready",
"progress" = "progress",
"complete" = "complete"
}
그리고 프론트에서는 이 상태에 따라 다른 컴포넌트를 보여줘야 한다.
그럼 아래와 같이 코드를 작성할 수 있을 것이다.
import React from 'react';
export function DownLoad({ status }) {
...logic
if (DownLoadStatus.ready === status) {
return <Loading />;
}
if (DownLoadStatus.progress === status) {
return <Progress />;
}
return <Complete />;
}
아니면 이렇게도 작성할 수 있을 거 같다.
import React from 'react';
export function DownLoad({ status }) {
...logic
return (
<>
{DownLoadStatus.ready === status && <Loading />}
{DownLoadStatus.progress === status && <Progress />}
{DownLoadStatus.complete === status && <Complete />}
</>
);
}
물론 이렇게 작성하여도 타입에 따라 알맞은 컴포넌트가 잘 동작한다.
하지만 아무리 봐도 우아하지 못한 방법인거 같다. 내가 만약 위처럼 코드를 작성해 놨다면 다른 동료 개발자는 또 저기에 수많은 조건식과 컴포넌트를 추가하며, 나중에는 저 컴포넌트는 더 길고 복잡하게 될 것이다.
사실 이건 실제로 내가 객관식 보기 컴포넌트를 만들면서 했던 고민이다. 객관식 보기 컴포넌트는 초기 기획에는 3개의 상태가 존재했다. 예를 들어 숫자만 있는 보기, 테이블형 보기, 리스트형 보기이다. 하지만 추후 서비스가 고도화됨에 따라 더 많은 리스트 컴포넌트가 생길 예정이었다. 그리고 서버에서도 보기에 따라 다른 타입의 데이터를 내려주고 있었다.
나는 위 사진의 After 부분처럼 컴포넌트를 만들기 위해 많은 것을 찾아봤고 훨씬 깔끔하게 동적으로 컴포넌트를 만드는 구조를 찾아냈다.
const StatusLookUpTable = {
[DownLoadStatus.ready]: Loading,
[DownLoadStatus.progress]: Progress,
[DownLoadStatus.complete]: Complete
};
interface StatusProps {
status?: DownLoadStatus;
}
export const Status: FC<StatusProps> = ({ status = DownLoadStatus.ready }) => {
return React.createElement(StatusLookUpTable[status]);
};
물론 타입스크립트를 사용하긴 하지만, 실제 프로덕션 환경에서 개발하였다면, 한 번 더 위 코드에 타입 가드를 주는 것을 추천한다(프런트는 서버를 신뢰하는 동시에 적절한 방어 코드도 짜 놔야 한다고 생각한다).
export const Status: FC<StatusProps> = ({ status = DownLoadStatus.ready }) => {
if (typeof StatusLookUpTable[status] !== "undefined") {
return React.createElement(StatusLookUpTable[status]);
}
return <div>오류가 발생했습니다. 고객센터로 문의 바랍니다.</div>;
};
오랜만에 글을 쓰면서 두서없이 쓴 거 같긴 한데, 도움이 되었으면 좋겠다.
예제 코드)
'React' 카테고리의 다른 글
[React] 간단하게 예제 코드로 구현해 보는 Drag and Drop (드래그앤드롭) (0) | 2021.01.10 |
---|---|
[React Dot Notation] 리액트 컴포넌트 점 표기법 (0) | 2020.12.25 |
React + Styled-components로 항상 보이는 스크롤 구현하기 (0) | 2020.07.26 |
React + Styled-components로 구현해본 아코디언(Accordion) (1) | 2020.07.26 |
CSS in 리액트 - Inline Style (0) | 2020.02.01 |