1

I was looking for a way to import my components dynamically, simply by using their name, after looking for a while i got to know about code splitting and things like React.lazy, react-loadable, and loadable-component, i made a few test case and after understanding how everything works i managed to implant it in my project and refactor my classes to work with this
The main issue i encountered was that a few things in my application broke, for example my checkbox not working and ... i managed to fix this after moving the dynamic import from inside the render to outside, within a function and then calling that function and passing a props to do a dynamic import, now another thing is broken and i'm afraid, more things such as this might happen, is this because of how the dynamic importing works?! should i stop using it ??, i spent the whole day trying to understand whats wrong with my previously working codes!
Now my question is, is there some kind of guide line i have to follow to use dynamic coding which i'm not and now its making my code break, or are these methods simply too experimental and kinda buggy in some cases?!, or maybe its too late for a project which is already half way through to add something like this to the project?,
Here is my code with its latest changes just so you get a rough idea of what i'm doing:

const AsyncPage = loadable(props => import(`${props.page}`))

class MyClassComponent extends Component {
    render  () {
        const importPath = './UI/' + UIType + '/' + UIType; 
        return (                            
            <AsyncPage page={importPath} {someOtherComponentProps}>{UIchildrens}</AsyncPage>
        )
    }
}

Any help and tips is much appreciated thanks.
Update01:
I managed to fix the current issue !, it seems that i had the same key in one of my maps and that had caused this particular issue!, the funny thing is this only happens after i added lazy loading ! and it works fine with the normal importing, strange but i guess they do mention not having a good key in map can cause weird problems

Ali Ahmadi
  • 701
  • 6
  • 27

2 Answers2

3

While using react-loadable I have found out if I put all my URL in a variable it cannot find the module and I get module not found error. But if I use a string literal for the base address then it will work. So for example the following did not work for me:

loader: () => import(item.url)

while this one work:

loader: () => import('./example/' + item.fileName)

MehranTM
  • 714
  • 9
  • 10
0

as mentioned in the react docs, you should use a combination of React.lazy and Suspense to get things running. You don't have to use other libraries, since React provides these already for you. So first for your import, which looks fine, but should be moved to use React.lazy:

const AsyncPage = React.lazy(() => import(`${props.page}`));

But that is only half of the process to get it running. Since you render the page directly in your render function, it will break while the page is loading. That is why you have to wrap all react.lazy calls within a Suspense component, which will render a fallback while the page is loading:

class MyClassComponent extends Component {
render  () {
    const importPath = './UI/' + UIType + '/' + UIType;         
    const AsyncPage = React.lazy(() => import(importPath));
    return (       
        <Suspense fallback={'...Loading}>            
            <AsyncPage {someOtherComponentProps}>{UIchildrens}</AsyncPage>
        </Suspense>         
    )
}}

This will display the fallback (Loading string), while the component is loading and will display the Page, after the download is complete. This should be working out of the box and it should not break and functionally, snceit is opt-in and plug and play without changes how your react code works.

Hope this helps. Happy coding.

Domino987
  • 8,475
  • 2
  • 15
  • 38
  • The reason i decided not to use the `React.lazy` and use other libraries is because it throws an error saying it can't find my module !! `Error: Cannot find module './UI/Card/Card`, now after some testing i got that React.lazy or the other libraries don't support relative or absolute(using `webpack`) path, so i moved my `UI` folder beside the class i wanted to do dynamic import from, this fixed the problem for third party libraries but React.lazy still doesn't find the modules! – Ali Ahmadi Aug 06 '19 at 12:00
  • Are you sung create-react.app? I am using it like this and it is relative and it just works: const Settings = React.lazy(() => import('../../containers/Routes/Settings')); So it is probably a webpack problem not a react.lazy problem. – Domino987 Aug 06 '19 at 12:08