How to Dynamically Render React Components

I am currently working on a React/Redux universally rendered application at work. It has some fun parts and I want to share what I’ve learned from building them.

One of those parts is a component I have called the BlocksLoop. In the design phase of the project, long before I was ever a part of the project, the designers and back end dev had the foresight to create a system of reusable admin components. They called them “blocks”. Each page of the application was to be architected by utilizing these blocks in different orders and patterns. This was a front-end developer’s dream come true. I considered crying, but then didn’t, mostly because I can’t. Seriously. I have some weird dry eye condition. I don’t create the same amount of tears as you normal, emotionally and physically healthy people. But I digress.

In the end, the designers came up with 10 reusable blocks for the project. The backend developer implemented an API that returned an array of objects. So, how do we handle rendering components when we have no idea how many, or specifically which ones we’ll need at any given time?

In my last blog post, I showed you how we can render different components conditionally. We’re going to take that a step further. Actually we’re going to take that to 11.

Inspired by the architecture of reducers in Redux, I realized a simple way to handle this very dynamic array of objects was to use a switch statement.

I knew that each object in the array had a type property. I needed to make individual components for each type. I could then check this type, and require the proper component with each one. This is significantly easier architecture than attempting to write a giant component to handle all the types. So let’s see how this works.

For this example, imagine that I have several built out components. Each of these components represents a type of block. We’re going to import these into what will become our BlocksLoop component. I’ll also setup our component to accept a blocks prop, but it won’t do anything important yet.

Right now, I’m just returning all the blocks as a simple div and not utilizing the imported individual blocks. Let’s solve that with a switch statement. To make it cleaner, we’ll move this logic into a method on the component that’s called each time a block item is mapped over.

And there you have it! Our blocks array is mapped over, each item is passed into our method, and the correct component is returned dynamically. If for some reason a type was added in the back end before I could make a new component for it, the method returns an empty div with a class I can style.

I think it might be possible to reduce some of the boilerplate in the switch statement by creating a variable, such as let dynamicComponent = null, and then overriding that assignment in each case with the correct component. Then in one last step in the function, I could add the key and {...block} props (via the Object spread operator) to the currently assigned dynamicComponent variable. I’m ok with being this explicit for now. It’s very legible and understandable.

If you find this useful, I’d love to hear about it in the comments. Or if you have a way to improve this, I’d love to hear that, too.

Interesting! From a front-end POV, this sort of sounds like you’re composing web components. Currently, I’m attempting to implement RiotJS components in a Drupal backed CMS. We have a lot of authors, and our WYSIWYG content could be considered similar to your BlockLoop component to which the custom RiotJS tags I’ve created are added.

Offloading most of the rendering of generic components of any kind to JS (via React, RiotJS, Polymer or what have you) instead of relying purely on HTML and a PHP rendering system (yuck!) seems like a good direction to go in since composing content/UI with components seems like a much more ergonomic way for content creators to, well, create.