How to render a component dynamically based on a JSON config
Rendering a component dynamically based on a JSON configuration is a widely used technique in web development. It offers several advantages, such as enhancing a component’s reusability and simplifying updates. To understand this concept further, let’s use a sample JSON configuration data as an example and demonstrate how to dynamically render a component in React code.
JSON config data
Let's take the following JSON config data as an example. We'll use this data in a code example to understand the dynamic rendering of React components.
[{ component: "text", content: "Hey fellas! Meet my pet cat Ziry!" },{ component: "image", src: "/cocomo.jpeg", alt: "My pet cat Ziry" },{ component: "button", label: "Done", action: "Done!" }];
The file hierarchy of the code example is given below:
Steps
Import the JSON config data in the main file App.js. If JSON config data is large, we can also create a separate config.json file and import it into our code using
import jsonConfig from './config.json';. However, in this example, we import the entire data in a constant arrayjsonConfig.
const jsonConfig = [{ component: "text", content: "Hey fellas! Meet my pet cat Ziry!" },{ component: "image", src: "/cocomo.jpeg", alt: "My pet cat Ziry" },{ component: "button", label: "Done", action: "Done!" }];
Create a separate React component for each element (image, text, button) in JSON config. To do so, first create a
componentsfolder in thesrcfolder of the React application.
Text component
Create a TextComponent.js file in src/components. The component textComponent receives its content from JSON config as props. The content is rendered as an <h2> </h2> HTML element using props, config referring to the component of type text in JSON config and content, i.e., the property of component of type text in JSON config.
const textComponent = (props) => (<h2 className="text">{props.config.content}</h2>);export default textComponent;
Image component
Create a new component file ImageComponent.js in src/components for the image element in JSON config data. The component imageComponent receives props from its parent. The props are used to render the <img/> HTML element using src and alt, i.e., the properties of the image element on JSON config.
const imageComponent = (props) => (<img className="image" src={props.config.src} alt={props.config.alt} ></img>);export default imageComponent;
Button component
For the button component, create a new file ButtonComponent.js in src/components. The component receives label and action as props. The onClick() event uses action props, and the label of the button is provided by using label props.
const buttonComponents = (props) => (<button className="button" onClick={()=> alert(props.config.action)}> {props.config.label}</button>);export default buttonComponents;
Now create a separate function to render all the components dynamically. For this, create a new file RenderFunction.jsx in the
srcfolder. Import all the components in this file.
import TextComponent from "./components/TextComponent";import ImageComponent from "./components/ImageComponent";import ButtonComponent from "./components/ButtonComponent";
Render all these components based on their component key component in JSON config. For this, first create an object Components that will map all the components with component keys.
const Components = {text: TextComponent,button: ButtonComponent,image: ImageComponent};
After this, create a function renderComponents responsible for rendering components. It'll first check if the key exists in the object. If it does, we'll use the React.createElement() function from the React library to create an instance of the component. Refer here to learn more about createElement().
Another argument config will be passed to React.createElement() as prop. This means that the config object will be available as props.config within the rendered component. This is a way to pass configuration data to the dynamically created component.
However, if the key doesn't exist in the object, the function renderComponents will return a message saying the component doesn’t exist.
const renderComponents = (config) => {if (typeof Components[config.component] !== "undefined") {return React.createElement(Components[config.component], {config: config});}return React.createElement(() => (<div>Can not find {config.component} component</div>));};
Now, create a
map()function in App.js that parses each element of JSON config and passes it as an argument to therenderComponents()function.
import Renderer from "./RenderFunction";export default function App() {const renderedComponents = jsonConfig.map((config) => Renderer(config));return <div>{renderedComponents} </div>;}
The entire output of the rendered components will be stored in renderedComponents.
Visual representation of code example
Here's a complete visual representation of the code example we've discussed above:
Code
Here's the complete executable code:
import React from "react";
const buttonComponents = (props) => (
<button className="button" onClick={()=>alert(props.config.action)}>{props.config.label}</button>
);
export default buttonComponents;
Free Resources