Home > Mobile >  React How to imperatively render a functional component
React How to imperatively render a functional component

Time:12-24

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.

  • Related