Reputation: 15
Thanks for taking time to read this.
I am new to React and I am struggling a bit to render dynamically components. Object received from API can be arbitrary nested to x number of levels and component names that need to be injected are received from BE.
I am getting response from API that looks something like this :
{
name: 'div'
components: [
componentOne: {
name: 'div'
components: [
{
name: 'p',
components: [...deeply nested]
},
{
name: 'h1',
components: [...deeply nested]
}
]
}
componentTwo: {
name: 'nav',
components: [...]
}
]
}
Upvotes: 0
Views: 1603
Reputation: 2994
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:
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)
Upvotes: 2