You will have to handle different kind of node (at least text) but it is just a matter of walking down a tree (the API response) and build a React node tree according to it:
so your node definition looks like this (this is pseudo grammar and not meant to be in your code):
node: {
type: 'element' | 'text' => the type will be needed,
name: string => a tag name (if it is a React element),
children: node[]
}
So an actual response from your api could be:
{
type: 'element',
name: 'div',
children: [
{
type: 'element',
name: 'div',
children: [
{
type: 'element',
name: 'h1',
children: [
{ type: 'text', value: 'Title 1' }
]
},
{
type: 'element',
name: 'p',
children: [
{ type: 'text', value: 'This is a paragraph' }
]
}
]
},
{
type: 'element',
name: 'nav',
children: []
}
]
}
We will pass this response parsed as an object to a generateTreeNode method:
/**
* @param {object} apiResponse
* @returns {ReactNode}
*/
function generateTreeNode(apiResponse) {
switch (apiResponse.type) {
case 'element':
return React.createElement(apiResponse.name, { children: apiResponse.children.map(child => generateTreeNode(child)) });
case 'text':
return apiResponse.value;
default: // no default
}
}
Note the recursive call will ensure the whole apiResponse tree is walked.
That's it. This is untested but should work quite nicely: the return of the generateTreeNode function can be used as the return value of a render method.
The main ressources you should understand to use it are what is a React Node and creating a react node.
Also, feel free (and you should) to extend your api response structure and walking to handle:
- custom components (that you will have to import somehow)
- additional elements props (such a style or classNames)
- etc...
Note also that this code assumes that the root of your response is one node (remember how React do not let you return several nodes at once in the render method, array and fragments aside, that's why)
<div> <p></p> <h1></h1> <div/> <nav></nav>The main problem is that I can't know how deep nesting will be, because user has ability to build his UI in CMS and to add as much components he wants in any structure he wants. So recursion was an option, but I am having problem to figure out the way when injecting components dynamically as children of components that were dynamically injected. (I hope i did not confuse you even more)