Tarlen
Tarlen

Reputation: 3797

Using React, how do I render components based on a type?

Say I have a list of Posting components which can be of type say, Car, Truck or Boat.

The props to render each type of posting are the same, only the layout differs.

Should I create a separate component for each type? (CarPosting, TruckPosting), then render the correct one based on the type prop, or should I just have a partial render method for each type in the Posting component, which I then switch and call from the main render method?

Upvotes: 1

Views: 1737

Answers (1)

Andre Pena
Andre Pena

Reputation: 59336

You should have a separate component for each posting and then a wrapper component should decide which inner component to render.

The inner components

You should definitely have a separate component for each type, (CarPosting, TruckPosting...). These components should not have a type attribute, because when they are rendered, whoever is rendering should know whether they are a CarPosting, for instance.

As for whether you should use inheritance for these components or not, that depends on how much they share in terms of logic. If they only share some prop names, that alone does not justify using inheritance. In fact, most of the times there will be no need for inheritance in React components. There are some ways you can share behavior among your components without inheritance, like using Mixins or simply sharing some JS modules. That's actually up to you.

The wrapper component

Now, a wrapper component should determine which child components to render based on their type.

Yes, you can do switch and choose the component within that switch. If you have only 2 or 3 component type and you don't care too much about extensibility, that is acceptable.

However, a more sophisticated way of solving it would have a ComponentFactory in which you register a type and a component, like this:

// the first parameter is the type, the second is the Component
componentFactory.register("car", CarPosting);
componentFactory.register("boat", BoatPosting);

The componentFactory can have a buildComponent method accepting props, and repassing the props to a new instance of the component, according to what you have registered.

Example:

componentFactory.buildComponent("boat", someBoatProps)

Now, from your wrapper component, you can call the componentFactory for generating the components for you. Like this:

// this is inside the render method
<div>
 {
     postings.map(posting => componentFactory.buildComponent(posting.type, someOtherProps))
 }
 </div>

Upvotes: 4

Related Questions