0
votes

Context for a good solution (short question in bottom).

I have a database (API) which generate list of data of apps like AppA, AppB, AppC, etc. with their name, path...

With a map, I generate (react router) links to these apps based on this data list (in the main <App/>) and front. With another identical map (below), I have made the router which should call the App based on the route and app name:

function(Router) {
    const [routes, setRoutes] = useState([]);

    useEffect(() => {
        fetch("MyAPI")
            .then(res => res.json())
            .then((result) => {setRoutes(result.results)}

            )
    }, [])

   // The route for each app and after the map, the route to the home with these links
    return (

        <Switch>{ 
            routes.map(result =>
                <Route exact path={"/"+result.route} key={keygen(16)}>
                    <AppCaller name={result.name} id={result.id} path={"/"+result.route}/>
                </Route>

            )}
            <Route exact path="/">
                <App />
            </Route>
        </Switch>

    )
}
export default Router

My first problem is I cannot neither give a component Name like <result.name/> from the API to call this component in the Router nor import dynamically this component. My first solution was to create another component <AppCaller/> with the name and path as Props to remove the component problem like this :

import React from "react";
import Window from "./dashComponents"
import subApp from "./Apps/Store"

 class AppCaller extends React.Component {

  render() {
    return (
        <Window name={this.props.name}>
            <subApp/>
        </Window>
    )
  }
}

export default AppCaller

In fact, I can keep the <subApp/> name even if the app is different. The only thing i need to change is the "where" is the app comes from.

Begin of short question

So, How can I change the path of the import statement to "import" the good App in this dynamic component ? (with a Props in this case)

import subApp from this.props.path 

This may looks like this (if it was static):

import subApp from "./Apps/App1" in the App1 file

import subApp from "./Apps/App1" in the App2 file etc.

Another idea seen in React Documentation and in Stack Overflow is to use Lazy Import but it does not works:

import React, {Suspense} from "react";
import Window from "./dashComponents"
//import subApp from "./Apps/Store"

    const path = this.props.path
    let name = this.props.name

 function AppCaller() {

    const SubApp = React.lazy(() => import('./Apps/'+name))


    return (
        <Window name={name}>
            <Suspense fallback={<h2>"Chargement..."</h2>}>
                <SubApp/>
            </Suspense>
        </Window>
    )

}

export default AppCaller

OR

 class AppCaller extends React.Component {

  render() {

    const SubApp = React.lazy(() => import('./Apps/'+this.props.name));

    return (
        <Window name={this.props.name}>
            <Suspense fallback={"Chargement..."}>
                <SubApp/>
            </Suspense>
        </Window>
    )
  }
}

export default AppCaller

"The above error occured in one of your React Component..."

Thank you for your help. I Try to be very accurate and find everywhere. So please, be free to tell me precision before judging.

Edit 1 with full Error

I have this error when I click in one of the links generated.

The above error occurred in one of your React components: in Unknown (created by AppCaller) in Suspense (created by AppCaller) in div (created by Window) in Window (created by AppCaller) in AppCaller (created by RoutesX) in Route (created by RoutesX) in Switch (created by RoutesX) in RoutesX in div in Router (created by BrowserRouter) in BrowserRouter

Consider adding an error boundary to your tree to customize error handling behavior. Visit 'Facebook' to learn more about error boundaries.

Edit 2 with initial Error

react-dom.development.js:11865 Uncaught ChunkLoadError: Loading chunk 0 failed. (error: http://dash.localhost:8000/0.main.js) at Function.requireEnsure [as e] (http://dash.localhost:8000/static/frontend/main.js:106:26) at eval (webpack:///./src/components/AppCaller.js?:45:36) at initializeLazyComponentType (webpack:///./node_modules/react-dom/cjs/react-dom.development.js?:1432:20) at readLazyComponentType (webpack:///./node_modules/react-dom/cjs/react-dom.development.js?:11862:3) ... requireEnsure @ main.js:106 eval @ AppCaller.js:45 ...

And

0.main.js:1 Failed to load resource: the server responded with a status of 404 (Not Found)

1
What is the full error message that appears when using React.lazy? You can click on edit to include details to your question.cbr
Thanks cbr for your answer, message edited with full error messageSMAX
Could you include the error that the message refers to? It says "the above error" - please add that error.cbr
Yes sorry, errors were filtered in chrome I did not see the the others errors :)SMAX
did you try using ES5 'require' insteadJake Lam

1 Answers

0
votes

Ok Everybody !

So, it was not a React but a Webpack problem !

When you use a React lazy to import specific component, and you "compile" with npm run dev (or build) webpack split the code by Chunck but the configuration file is wrong. Here's my configuration file which works:

module.exports = {
    output: {
    filename: 'App.js',
    publicPath: '/static/frontend/',
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        use: {
          loader: "babel-loader"
        }
      }
    ]
  }
};

I needed to add the "public path" to the path of the "chunck' scripts. :)