Dynamic Component & Lazy
TOC
필요성
1.페이지 증가에 따른 유지보수 이점
2.불필요한 js 호출 최소화 & 초기 렌더링 성능 최적화
사전 작업
1.DB & Front의 메뉴 경로를 매핑
2.node.js 의 `glob` 객체를 활용한 페이지 경로 접근
( 배포 후 페이지의 접근을 가능하게 해줌 )
해결 방법
#동적 컴포넌트 생성
import { lazy, Suspense } from "react";
import { Spin } from "antd";
const componentPages: any = import.meta.glob("../pages/**/**/**.tsx");
const DynamicPathComponent = (props: any) => {
const LazyComponent = lazy(
typeof componentPages[props.componentPath] === "function" ? componentPages[props.componentPath] : () => {}
);
return (
<Suspense fallback={<Spin tip="Loading" size="large"></Spin>}>
<LazyComponent />
</Suspense>
);
};
export default DynamicPathComponent;
#Router에 모든 페이지 적용
const FncChildrenPathAndElement = (totalMenu) => {
const childrenMenuArr: ChildrenProps[] = totalMenu
.map((list) => (list.children !== null ? list.children : []))
.map((arr) => arr.map((obj) => (obj.menuUrl !== null ? obj.menuUrl : [])))
.filter((val, idx) => val.length > 0)
.join()
.split(",")
.map((path) => {
return {
path: path.split("..")[1].split(".tsx")[0],
element: <DynamicPathComponent componentPath={path} />,
errorElement: <ElementComponentError />
};
});
return childrenMenuArr;
};
const dynamicMenuPages = [
{
path: "/login",
element: <LoginLayout />,
children: [{ index: true, element: <Login />, errorElement: <ElementComponentError /> }],
errorElement: <Error />
},
{
path: "/",
element: <MainLayout _Menu={totalMenuList} />,
children: defaltMainMenu.concat(...childrenMenuList),
errorElement: <Error />
},
];
setDynamicPage(createBrowserRouter([...dynamicMenuPages]));
(이하 소스 생략)
...
return <>{isLoading && <RouterProvider router={dynamicPage} />}</>;
