Динамический импорт компонента в React на основе записей конфигурации - PullRequest
0 голосов
/ 20 ноября 2018

У меня есть несколько приложений как часть одного проекта React-redux-typcript.Все эти отдельные приложения являются частью основного приложения.Я хочу динамически настроить маршрутизацию.

Мои текущие маршруты выглядят так:

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 голосов
/ 01 декабря 2018

Мне удалось использовать динамический импорт для достижения этой цели.Я использовал эту статью, чтобы понять несколько концепций.

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

Одно из важных отличий заключается в том, что если я не укажу путь из корня приложения, я получаю сообщение об ошибке «Невозможно найти модуль».Вот почему я дал полный путь от корня.

...