如何根据state.showModal的值动态导入并渲染对应的React组件
解决方案
1. 按需加载仅需的单个组件
可通过React内置的React.lazy和Suspense实现代码分割,两个模态框组件不会被打包到初始资源包中,仅当对应模态框需要展示时才会加载对应组件的资源,减少初始加载体积。
如果不需要代码分割,只是想简化渲染逻辑可以跳过这部分,直接看第二节的映射方案。
2. 简化渲染逻辑实现类<showModal />的调用方式
通过对象映射关联showModal的取值和对应组件,不需要编写多条条件判断语句,后续新增模态框类型只需要更新映射对象即可,可扩展性更强。
完整修改后的代码示例
import { ReactElement, lazy, Suspense } from 'react'; import { LayoutShape } from '../interfaces/state'; // 组件名和组件实例的映射,实现懒加载 const ModalComponents = { // 适配具名导出的组件,如果是默认导出可去掉.then部分,直接写import('../components/SignIn') SignIn: lazy(() => import('../components/SignIn').then(mod => ({ default: mod.SignIn }))), Join: lazy(() => import('../components/Join').then(mod => ({ default: mod.Join }))) } as const; export interface PropsShape { children: ReactElement; state: LayoutShape; isSignedIn?: boolean; } const Layout = ({ children, state, isSignedIn }: PropsShape): ReactElement => { const { showNavAlert, isNavVisable, isFooterVisable, showFooterAlert, showModal, showLeftMenu, showRightMenu, } = state; // 首字母大写才能被JSX识别为React组件 const CurrentModal = ModalComponents[showModal as keyof typeof ModalComponents]; return ( <div className='Layout'> {showModal !== 'none' && CurrentModal && ( <div className='Layout--modal' data-testid='showModal'> {/* Suspense的fallback可替换为你需要的加载态组件 */} <Suspense fallback={<div>加载中...</div>}> <CurrentModal /> </Suspense> </div> )} {/* 其余原有逻辑保持不变 */} {children} </div> ); };
不需要懒加载的简化版本
如果不需要代码分割,只是想简化条件判断,直接用静态导入加映射即可:
import { ReactElement } from 'react'; import { LayoutShape } from '../interfaces/state'; import { SignIn } from '../components/SignIn'; import { Join } from '../components/Join'; const ModalComponents = { SignIn, Join } as const; // 其余代码和上面一致,渲染时不需要包裹Suspense
注意事项
- 你不能直接写
<showModal />,因为JSX会把小写开头的标签识别为原生HTML标签,必须赋值给首字母大写的变量后再渲染。 - 如果后续新增模态框类型,只需要在
ModalComponents中新增对应键值对即可,不需要修改渲染逻辑。
内容的提问来源于stack exchange,提问作者Bill
相关产品推荐
相关产品推荐

