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

时间:2018-11-20 18:30:41

标签: reactjs typescript ecmascript-6 import router

我有多个应用程序作为一个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必须动态,以便添加新应用是配置问题,因此我无法在顶部进行导入,因为我不知道要在配置中添加什么。谢谢。

1 个答案:

答案 0 :(得分:0)

我能够使用动态导入来实现这一目标。我使用this文章来了解一些概念。

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

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