How to create a dynamic layout in react with fully configurable JSON data

Viewed 128

I am writing a react application. A core requirement is that the application be completely dynamic and configurable, including choosing layouts, sections and fields, validation etc. I have two UI. One is the config UI where the user can select the layout, sections, fields like what type of html component etc. Once this is saved, I get data as JSON where I need to draw the UI. This is my second UI. My concern is how do I structure the components to render the UI with the JSON data. The fields & sections will be same but the layout will be different based on what is been selected in the config UI. Below is the rough JSON schema.

{
  title: "Test title",
  layout: [
    {
      name: "layout-a"
    },
    sectionA: {
      name: "breadcrumbs"
      field: [
        {
          name: "test",
          value: "test",
          type: "text"
        }
      ]
    },
    sectionB: {
      name: "actions"
      field: [
        {
          name: "Create",
          value: "Create",
          type: "button"
        }
      ]
    }
  ]
}

I was thinking of having a layout component which renders all the children from the JSON. Component looks like below

const Layout = ({ children }) => {
  return (
    <div>
      <div className="container">
        <div className="content">{children}</div>
      </div>
    </div>
  );
};

and top level component where we read the config json and based on the layout render the component

<Layout>
      {viewToShow === "layoutA" && <LayoutA data={config.sections} />}
      {viewToShow === "layoutB" && <LayoutB data={config.sections} />}
</Layout>

My question is how do I construct the LayoutA, B or C component so that these sections and fields are rendered differently on the UI?

1 Answers

I think your question leaves a lot of unspecified points for us to offer you a proper solution. My advice is to investigate better what the project real needs are and its main goals, then lay out each piece (component) thoroughly checking what should be "configurable" and to which extent, before coming up with any implementation.

Taking your example "as is", my first thought is to wrap your App component into a Context provider, similar to what we'd do to manage themes.

export const layouts = {
  layoutA: {
    background: '#fff',
    sectionWidth: '100%',
  },
  layoutB: {
    background: '#000',
    sectionWidth: '50%',
  },
};

export const LayoutContext = React.createContext({
  layout: layouts.layoutA, // default layout
  toggleLayout: () => {},
})

You could then further populate the layouts object with metadata from a database. Supposing changes do not originate from the UI (think Webflow or Wix Editor), you could use a CMS to update the metadata and propagate the changes.

An example usage would be:

function LayoutTogglerButton() {
  return (
    <LayoutContext.Consumer>
      {({ layout, toggleLayout }) => (
        <button
          onClick={toggleLayout}
          style={{ backgroundColor: layout.background }}>
          Toggle Layout
        </button>
      )}
    </LayoutContext.Consumer>
  )
}

Again, there are a lot of unspecified points on your request for us to be more specific. The request for "an application to be completely dynamic and configurable, including choosing layouts, sections and fields, validation etc" could mean many things.

Examples of more specific questions: How to create dynamic forms in React with functional components? How to create drag and drop dashboard widgets with React? How to live update/customise themes with styled-components?

Perhaps you could be more specific? Cheers

Related