根据配置条目在 React 中动态导入组件

Posted

技术标签:

【中文标题】根据配置条目在 React 中动态导入组件【英文标题】:Dynamically import component in React based on config entries 【发布时间】:2019-04-23 06:30:01 【问题描述】:

我有多个应用程序作为一个 React-redux-typescript 项目的一部分。所有这些单独的应用程序都是核心应用程序的一部分。我想动态设置路由。

我当前的路线如下所示:

Routes.tsx

import HomePageApp  from "../Components/Home/HomeApp";
import TestApp from "../Components/Test/TestApp";
export default function Routes() 
  return (
    <Switch>
        <RedirectIfAuthenticated
        exact=true
        isAuthenticated=true
        path=Path.homePath --> "/"
        component=HomePage ---> AppName coming from import statement on top
        redirectPath=Path.homePath -->  "/"
        />
        <RedirectIfAuthenticated
        isAuthenticated=true
        path=Path.apps.test --> "/test"
        component=TestApp --> AppName from import on top
        redirectPath=Path.homePath --> "/"
        />
     </Switch>
   );

并且 RedirectIfAuthenticated 只是重定向到正确的应用程序的登录页面。

RedirectIfAuthenticated.tsx

export default function RedirectIfAuthenticated(
    component,
    redirectPath,
    isAuthenticated,
    ...rest
: IRedirectIfAuthenticatedProps) 
    const Component = component;
    const render = (renderProps: RouteComponentProps<any>) => 
        let element = <Component ...renderProps />;
        return element;
    ;

    return <Route ...rest render=render/>;

我有一个这样的配置文件:

Manifest.ts

export let manifest = 
  apps: [
    
      componentPath: "/Test/App",
      path: "/test",
      name: "Test"
    ,
   ...more objects for other apps
  ]
;

在我的 Routes.tsx 中,我想利用我的清单来呈现 RedirectIfAuthenticated 组件。

所以我可以弄清楚这个变化:

为了简洁起见,展示了肮脏的方法,但实际代码使用 .map 遍历清单并呈现 RedirectIfAutenticated。

const app = manifest.apps.find(app => app.name === "Test");
<Switch>
  <RedirectIfAuthenticated
  isAuthenticated=true
  path=app.path --> "/test"
  component=What should I do here? How to pass component reference by path?? 
  redirectPath="/" ==> I typically get this from my manifest..
  />
</Switch>

一种选择是这样做:

component=require("path from manifest").default

但是我们的 tslint 会抛出一堆错误。除此之外,我无法弄清楚如何在此处动态传递组件引用。寻找更好的方法。

Routes.tsx 需要是动态的,以便添加新应用程序是一个配置问题,因此我不能在顶部进行导入,因为我不知道要在配置中添加什么。谢谢。

【问题讨论】:

如果您的 React 版本是 v16.6.x,那么您可以尝试使用 React.lazy 执行类似 component=React.lazy(() =&gt; import("path from manifest")) 的操作 .default 和 lazy,因为它已经完成自动地。也可以参考我的无耻插件:Loading React Components Dynamically on Demand 【参考方案1】:

我能够使用动态导入来实现这一点。我用this的文章理解了几个概念。

 private loadComponentFromPath(path: string) 
    import(`../../ScriptsApp/$path`).then(component =>
      this.setState(
        component: component.default
      )
    );
  

这里的一个重要区别是,如果我不提供应用程序根目录的路径,我会收到一条错误消息“无法找到模块”。这就是为什么我给出了根目录的完整路径。

【讨论】:

以上是关于根据配置条目在 React 中动态导入组件的主要内容,如果未能解决你的问题,请参考以下文章

十react-router 4.x的基本配置

如何使用 Shebang Loader 配置 Webpack 以忽略 Hashbang 将 Cesium React 组件导入 Typescript React 组件

我在设置我的 jest 配置时遇到问题 react native 无法导入组件

来自配置的 React 和 Typescript 动态组件

使用 React 创建动态 UI

react-route动态路由,它的子路由路径配置在啥地方