0
votes

I have a react app where user navigations/components comes from backend as array and stored in localstorage.

Sample navigation property;

{
    component: "dashboard",
    fileUrl: "./views/dashboard/analytics/AnalyticsDashboard",
    icon: "Home",
    id: 1,
    name: "view",
    type: "item",
    url: "dashboard",
}

All components are are wrapped with lazy loading feature. So, what I tried is;

Lazy component array

import userNavigation from './configs/userNavigation'

const lazyComponents = userNavigation.reduce(function (result, item) {
  var key = item.component;
  result[key] = lazy(() => import(`'${item.fileUrl}'`));
  return result;
}, {});

AppRouter component render

render() {
    
    const dynamicRoutes = userNavigation.map(({id, url, component}) => 
        <RouteConfig key={id} path={url} component={lazyComps[component]}></RouteConfig>  
    )

    return (
      <Router history={history}>
        <Switch>
          <RouteConfig exact path="/" component={Landing} fullLayout />
          {dynamicRoutes}
          <RouteConfig path="/login" component={Login} fullLayout />
          <RouteConfig path="/register" component={register} fullLayout />
          <RouteConfig component={error404} fullLayout />
        </Switch>
      </Router>
    )
  }

RouterConfig is a wrapping component of Route for configuration;

const RouteConfig = ({ component: Component, fullLayout, ...rest }) => (
  <Route
    {...rest}
    render={props => {
      return (
        <ContextLayout.Consumer>
          {context => {
            let LayoutTag =
              fullLayout === true
                ? context.fullLayout
                : context.state.activeLayout === "horizontal"
                  ? context.horizontalLayout
                  : context.VerticalLayout
            return (
              <LayoutTag {...props} >
                <Suspense fallback={<Spinner />}>
                  <Component {...props} />
                </Suspense>
              </LayoutTag>
            )
          }}
        </ContextLayout.Consumer>
      )
    }}
  />
)

So the problem is dynamic routes are rendered, but they are not working. I can see all routes. /login, ./register routes are working fine but dynamically rendered routes are fallbacks to /error404. Btw, when I inspect Switch, I see Routes as in the picture, might it be because of `dynamic routes are rendered as array?

enter image description here

1

1 Answers

0
votes

The problem is about webpack dynamic loading, you can't pass the import url as a whole parameter, you must add a existing prefix first;

Not Working

const fileUrl = "path/to/file";
lazy(() => import(fileUrl))

Working

lazy(() => import("./path/to/" + filePath))

About the issue