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.
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:
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 array jsonConfig.
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 components folder in the src folder of the React application.
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;
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;
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 src folder. 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 the renderComponents() 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.
Here's a complete visual representation of the code example we've discussed above:
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