Say I'm making a React dashboard component. It can be full of React widgets, each of which may be different and re-orderable.
I import each widget like this:
import SomeComponent1 from './SomeComponent1.tsx';
import SomeComponent2 from './SomeComponent2.tsx';
import SomeComponent3 from './SomeComponent3.tsx';
// ... and so on.
I have an array of widgets like this:
const widgets = [
{sortOrder: 7, component: SomeComponent1},
{sortOrder: 10, component: SomeComponent2},
{sortOrder: 12, component: SomeComponent3},
// ... and so on. You get the idea.
]
Then I want to display them. My first attempt is something like this:
return (
<section style={styles.dashboardWrapper}>
{[...widgets]
.sort((a: Widget, b: Widget) => a.sortOrder - b.sortOrder)
.map((widget: Widget, i: number) => <DashboardWidget key={i}>{widget.component}</DashboardWidget>)
}
</section>
)
The {widget.component}
of course doesn't work. This is a piece of cake in Svelte because of <svelte:component this={widget.component} />
. So how do you do it in React?
CodePudding user response:
In your case it's quite simple: Instead of {widget.component}
do <widget.component />
. If necessary, you can also pass in props, as in <widget.component index={i} example="hello" />
Note: Normally, using a lower case letter at the start of a JSX element for a custom component isn't allowed, since lower case elements are reserved for built in elements, like <div>
or <span>
. You can get away with it your case because you've got a .
in there, and that makes it unambiguous that this is not a built in element.
So if you run into a case where the casing is a problem, simply assign the component to a different variable which has an upper case letter and use that:
const Component = widget.component;
return <DashboardWidget key={i}><Component /></DashboardWidget>
CodePudding user response:
You just have to update your widgets declaration to this:
const widgets = [
{sortOrder: 7, component: <SomeComponent1 />},
{sortOrder: 10, component: <SomeComponent2 />},
{sortOrder: 12, component: <SomeComponent3 />},
// ... and so on. You get the idea.
]
It should work fine in your case.