DEV Community

Cover image for Dynamically Render Components Based on Configuration
Reme Le Hane
Reme Le Hane

Posted on • Originally published at remejuan.substack.com

Dynamically Render Components Based on Configuration

When building apps, you often encounter situations where you need to render different components or layouts based on data. Instead of using a lot of if-else or switch statements, you can use a configuration-driven approach for cleaner and more scalable code.


Example: Dynamic Rendering with a Component Map

Let’s dynamically render different input fields based on a configuration object.

import React from "react";

// Components for different input types
const TextInput = ({ label, name, value, onChange }) => (
  <div>
    <label>{label}:</label>
    <input
      type="text"
      name={name}
      value={value}
      onChange={onChange}
    />
  </div>
);

const NumberInput = ({ label, name, value, onChange }) => (
  <div>
    <label>{label}:</label>
    <input
      type="number"
      name={name}
      value={value}
      onChange={onChange}
    />
  </div>
);

const Checkbox = ({ label, name, checked, onChange }) => (
  <div>
    <label>
      <input
        type="checkbox"
        name={name}
        checked={checked}
        onChange={onChange}
      />
      {label}
    </label>
  </div>
);

// Component map for dynamic rendering
const componentMap = {
  text: TextInput,
  number: NumberInput,
  checkbox: Checkbox,
};

// Configuration object for form fields
const formConfig = [
  { type: "text", label: "Name", name: "name" },
  { type: "number", label: "Age", name: "age" },
  { type: "checkbox", label: "Subscribe to Newsletter", name: "subscribe" },
];

const DynamicForm = () => {
  const [formData, setFormData] = React.useState({
    name: "",
    age: "",
    subscribe: false,
  });

  const handleChange = (e) => {
    const { name, value, type, checked } = e.target;
    setFormData((prev) => ({
      ...prev,
      [name]: type === "checkbox" ? checked : value,
    }));
  };

  return (
    <form>
      {formConfig.map((field) => {
        const Component = componentMap[field.type];
        return (
          <Component
            key={field.name}
            label={field.label}
            name={field.name}
            value={formData[field.name]}
            checked={formData[field.name]}
            onChange={handleChange}
          />
        );
      })}
      <button type="submit">Submit</button>
    </form>
  );
};

export default DynamicForm;
Enter fullscreen mode Exit fullscreen mode

How It Works

1. Component Map:

  • A mapping (componentMap) links input types (e.g., "text", "checkbox") to specific React components.

2. Configuration Object:

  • The formConfig array defines the structure of the form, including each field’s type, label, and name.

3. Dynamic Rendering:

  • The formConfig array is iterated over, and the appropriate component is rendered dynamically based on the field type.

4. Single State Object:

  • Form state (formData) is managed in a single object, updated dynamically based on input changes.

Benefits

  • Scalability: Easily add new field types or forms by extending the formConfig and componentMap without changing the core logic.

  • Reusability: The components and configuration can be reused across multiple forms.

  • Readability: Eliminates repetitive JSX and if-else logic, making the code more concise.


When to Use This

  • When you need to dynamically render components (e.g., forms, modals, or dashboards).

  • When your app has repetitive but configurable UI patterns.

  • When you want a cleaner, more modular architecture.


This technique is a game-changer for building flexible and reusable UI components in React! Let me know how you’d use this in your project!

Top comments (0)