React.js
특정한 state 값에 따른 다른 페이지 랜더링을 효율적으로 랜더링 하는 방법에 대해
Dev갱이
2024. 5. 19. 19:10
728x90
const ScheduleSidebar: FC<ScheduleSidebarProps> = ({
isSelecteGroup,
isScheduleName,
isStartEndPeriod,
isPage,
}) => {
return (
<div
className={cn(styles.right_sidebar_container, {
[styles.mobile_toruism_sidebar]: isPage === 'tourismPage',
})}
>
{isPage === 'tourismPage' && (
<SidebarScheduleTourism
isSelecteGroup={isSelecteGroup}
isScheduleName={isScheduleName}
isStartEndPeriod={isStartEndPeriod}
isPage={isPage}
/>
)}
{isPage === 'periodPage' && <SidebarSharedMembers />}
...
...
...
{/* 계속 쭉쭉 늘어날거에요! 가독성이 안좋습니다 */}
</div>
);
};
export default ScheduleSidebar;
isPage 상태값에 따라 `&&` 연산자를 통해서 다른 컴포넌트를 렌더링 하게끔 만들게 되었을때 가독성이 굉장히 안좋아보인다.
// 호출 부모 컴포넌트
<ScheduleSidebarController
isSelecteGroup={isSelecteGroup}
isScheduleName={isScheduleName}
isStartEndPeriod={isStartEndPeriod}
isPage={isPage}
status={isPage}
/>
// const
export const schdulePages = [
'selectGroupPage',
'periodPage',
'tourismPage',
] as const;
// controller를 담당하는 컴포넌트
const StatusScheduleSidebar = {
[schdulePages[1]]: SidebarSharedMembers,
[schdulePages[2]]: SidebarScheduleTourism,
};
interface StatusProps extends ScheduleSidebarProps {
status: (typeof schdulePages)[1 | 2];
}
const ScheduleSidebarController: FC<StatusProps> = ({ status, ...rest }) => {
if (typeof StatusScheduleSidebar[status] !== 'undefined') {
return React.createElement(StatusScheduleSidebar[status], rest);
}
return <div>오류가 발생했습니다. 고객센터로 문의 바랍니다.</div>;
};
export default ScheduleSidebarController;
`createElement`는 첫번째 인자값이 컴포넌트, 두번째 인자값이 props, 세번째 인자값이 children이다.
배열로 const를 선언하여 배열 인덱스 접근법으로 접근하는 방식이 불편하다면 객체 const를 만들어서 사용하면 된다. 아래 예제 참고
// const
export const LayerMode = {
linkInvite: 'linkInvite',
emailInvite: 'emailInvite',
groupDeleteConfirm: 'groupDeleteConfirm',
createFeed: 'createFeed',
feedDeleteConfirm: 'feedDeleteConfirm',
commentDeleteConfirm: 'commentDeleteConfirm',
logoutConfirm: 'logoutConfirm',
editProfile: 'editProfile',
selectedContentType: 'selectedContentType',
serviceCategory: 'serviceCategory',
areaCode: 'areaCode',
tourismDetail: 'tourismDetail',
scheduleDeleteConfirm: 'scheduleDeleteConfirm',
scheduleThumbnailImage: 'scheduleThumbnailImage',
} as const;
// controller
const StatusLookUpTable = {
[LayerMode.emailInvite]: EmailInvite,
[LayerMode.linkInvite]: LinkInvite,
[LayerMode.groupDeleteConfirm]: GroupDeleteConfirm,
[LayerMode.createFeed]: CreateFeed,
[LayerMode.feedDeleteConfirm]: FeedDeleteConfirm,
[LayerMode.commentDeleteConfirm]: CommentDeleteConfirm,
[LayerMode.logoutConfirm]: LogOutConfirm,
[LayerMode.editProfile]: EditProfile,
[LayerMode.selectedContentType]: ContentType,
[LayerMode.serviceCategory]: ServiceCategory,
[LayerMode.areaCode]: AreaCode,
[LayerMode.tourismDetail]: TourismDetail,
[LayerMode.scheduleDeleteConfirm]: ScheduleDeleteConfirm,
[LayerMode.scheduleThumbnailImage]: ScheduleThumbnailImage,
};
interface StatusProps {
status: Union<typeof LayerMode>;
}
const LayerModalControll: FC<StatusProps> = ({ status }) => {
if (typeof StatusLookUpTable[status] !== 'undefined') {
return React.createElement(StatusLookUpTable[status]);
}
return <div>오류가 발생했습니다. 고객센터로 문의 바랍니다.</div>;
};
export default LayerModalControll;
728x90