Maybe there is a better way, but I try to make my React components as reusable as possible. So I am using a bootstrap Card and inside this Card I wanna place different components from outside (with props) dynamically. Without props it works fine. But with props I got an error message "Error: Cannot find module '../../pages/Dummy'".
This works perfect:
import React, {Suspense} from 'react';
import { MDBCard, MDBCardBody } from "mdbreact";
const Area = (props) => {
const OtherComponent = React.lazy(() => import('../../pages/Dummy'));
return (
<MDBCard className="text-center">
<MDBCardBody>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent/>
</Suspense>
</MDBCardBody>
</MDBCard>
);
};
export default Area;
This doesn't work:
import React, {Suspense} from 'react';
import { MDBCard, MDBCardBody } from "mdbreact";
const Area = (props) => {
const OtherComponent = React.lazy(() => import(props.compName));
return (
<MDBCard className="text-center">
<MDBCardBody>
<Suspense fallback={<div>Loading...</div>}>
<OtherComponent/>
</Suspense>
</MDBCardBody>
</MDBCard>
);
};
export default Area;
Call from outside:
<Area compName='../../pages/Dummy'/>
It's like I cannot lazy-load with props. Very strange.
Btw. I don't need to use lazy-loading if there is an easier way to use sub-components dynamically. I just thought this is the only way.
There are a few options:
The first one uses 'slots,' which you can read about in the React docs here, or an article here.
const DummyOne = React.lazy(() => import('../../pages/DummyOne');
const DummyTwo = React.lazy(() => import('../../pages/DummyTwo');
const Area = ({ comp }) => {
return (
<MDBCard className="text-center">
<MDBCardBody>
<Suspense fallback={<div>Loading...</div>}>
{comp}
</Suspense>
</MDBCardBody>
</MDBCard>
);
}
// You dynamically pass the component itself into 'Area'
<Area comp={<DummyOne />} />
The second option is closer to what you have:
const Area = ({ compName }) => {
const components = {
DummyOne: React.lazy(() => import('../../pages/DummyOne'),
DummyTwo: React.lazy(() => import('../../pages/DummyTwo'),
}
const DynamicComponent = components[compName];
return (
<MDBCard className="text-center">
<MDBCardBody>
<Suspense fallback={<div>Loading...</div>}>
<DynamicComponent />
</Suspense>
</MDBCardBody>
</MDBCard>
);
}
// You dynamically pass the component name to 'Area' as a string
<Area compName="DummyOne" />