I am trying to import a module in react, based on an if condition. I have read that the import statement returns a promise. However, I cannot find a way to solve this. The code works when I import the module statically, but it does not work with dynamic import:
list.js
// import WelcomeGuide from './guide'; //this one works
const show_deprecated_guide = '';
const WelcomeGuide = (props) => ( // this one throws an error
import(`${!show_deprecated_guide ? `./guide.js` : `./guide-deprecated.js`}`)
.then( (Module) => (
Module.default
)
)
.catch ((err) => (
console.log(err)
)
)
)
const WelcomeList = (props) => {
// loading state..
if (!posts) return <div className="guide-list"><Spinner /></div>;
// loaded state
return (
<Fragment>
<WelcomeGuide/>
</Fragment>
)
};
export default WelcomeList;
guide.js
const WelcomeGuide = (props) => {
return (
<p>Welcome!</p>
)
}
export default WelcomeGuide;
I know I can jut import both components statically and render them conditionally, but it seems better for performance if I can import them based on the data I have. So, my question is: How to correctly import the module when using if statement? I read a lot of tutorials and I understand that the error is pretty self-explanatory, but I still cannot solve this one. Any help will be appreciated!
CodePudding user response:
I'm not 100% sure to understand your problem but I would say you need to import both guides and use the condition on the render like that :
import Guide from './...'
import DeprecatedGuide from './...'
const WelcomeList = ({ show_deprecated_guide }) => {
return (
<div>
{ show_deprecated_guide ? <DeprecatedGuide /> : <Guide /> }
</div>
)
}
CodePudding user response:
That's definitely not how you render a component in react.
If this is to work, it should look something like:
const WelcomeGuide = (props) => ( // this one throws an error
import(show_deprecated_guide ? './guide.js' : './guide-deprecated.js')
.then((Module) => (<Module />))
.catch ((err) => {
console.log(err)
}
)
)
Moreover, react already has a solution for doing things like that. It comes as a utility function: lazy
To use it in this case, you can do something like:
const Guide = React.lazy(() => import('./guide.js'));
const GuideDeprecated = React.lazy(() => import('./guide-deprecated.js'));
const WelcomeGuide = (props) => (
<Suspense fallback={<div>Loading...</div>}>
show_deprecated_guide ? (<Guide />) : (<GuideDeprecated />)
</Suspense>
)
Note the use of Suspense
around the lazy loaded components. You can have Suspense
further up in the tree and it will still work.
Read more about code splitting here