Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically import component in React based on config entries

I have multiple apps as part of one React-redux-typescript project. All of these individual apps are part of a core-application. I want to dynamically set up routing.

My current routes look like this:

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>
   );
}

And RedirectIfAuthenticated simply redirects to correct applications' landing pages.

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}/>;
}

I've a config file like this:

Manifest.ts

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

In my Routes.tsx, I want to make use of my manifest to render the RedirectIfAuthenticated component.

so I can figure out this change:

for brevity showing the dirty approach but the actual code iterates over the manifest using .map and renders 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>

One option is to do this:

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

but our tslint throws a bunch of errors at this. Other than this I can't figure out how to pass the component reference here dynamically. Looking for a better approach.

The Routes.tsx needs to be dynamic so that adding new apps is a matter of configuration so I can't do imports on top because I dont know what's gonna be added in config. Thanks.

like image 310
clever_bassi Avatar asked Mar 13 '26 04:03

clever_bassi


1 Answers

I was able to use dynamic imports to achieve this. I used this article to understand a few concepts.

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

One important distinction here is if I don't give the path from the root of the app, I get an error saying "Unable to find the module". This is why I've given the full path from the root.

like image 173
clever_bassi Avatar answered Mar 14 '26 19:03

clever_bassi



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!