Home > Mobile >  Use recursion to create react components dynamically at runtime from a json
Use recursion to create react components dynamically at runtime from a json

Time:07-27

I am trying to create functionality similar to Wix, where widgets can be dragged and dropped and their properties adjusted to create a unique layout. For this reason I store the widgets as nested json document using which I want to create react component tree dynamically at runtime

nestedJson = [{
   "_uid": "gbKyzEom", 
   "component": "div", 
   "children": [{
     "_uid": "hrykbdm", 
     "component": "span"
   }, {
     "_uid": "opeFbVcd", 
     "component": "h1"
   }]
}]

I have managed to create a intermediate json representation where I have been able to represent to component depth and it's relationship to the parent component. For ex:

depthInfo = [{1 : {params: ['div', null], Id: "gbKyzEom"}}, {2: {params: ["span", null], id: "hrykbdm", parentId:"gbKyzEom" }},  {2: {params: ["h1", null], id: "opeFbVcd", parentId:"gbKyzEom" }} ]

I would like to create the component tree using depthInfo using recursion, like so

React.createElement.apply(null, ['div', null, React.createElement.apply(null, ['span', null]), React.createElement.apply(null, ['h1', null])]) 

CodePudding user response:

If I read correctly, this may be as simple as the following:

// dummy for testing -- just creates a string
const React = {createElement: (tag, props, children) => `<${tag}>${children.join('')}</${tag}>`}

const reactify = components => components .map (
  ({component, children = [], ...rest}) =>
    // do something with other properties?
    React .createElement (component, null, reactify (children))
)

const components = [{_uid: "gbKyzEom", component: "div", children: [{_uid: "hrykbdm", component: "span"}, {_uid: "opeFbVcd", component: "h1"}]}]

console .log (reactify (components))
  

Our input is in the exact same format as are its (recursive) children nodes, so we have a simple recursion.

I've shimmed React here, but the real thing shouldn't be much different. Of course this returns an array of React components (or strings in my shim), so there may be a need to wrap the result in a single container.

I don't think your depthInfo intermediate data is needed for anything, but perhaps I'm missing a subtlety.

  • Related