[devalue: Cannot stringify a function] Can't get dynamic component tree to SSR properly
See original GitHub issueHey there,
First of all, I’m sorry that I have to open this issue here, I’m quite new to SSR and it’s probably possible to find my answers somewhere somehow, though I’m already pretty stressed out as I don’t understand what’s going wrong and that I don’t understand it 🤯😅
So I’m trying to render the following JSON
{
"title": "CanRau.com Homepage",
"content": [
{
"component": "section",
"props": {
"className": "bg-nord1 mx-auto pt-2 text-nord5",
"key": "indexSection"
},
"children": [
{
"component": "Hero", <-- Here lies the problem
"props": {
"className": "bg-primary",
"key": "indexHero"
}
},
{
"component": "h1",
"props": {
"className": "bg-red",
"key": "indexH1"
},
"children": "H1"
}
]
}
]
}
Everything works fine until I introduce custom components like "component": "Hero"
which will be replaced with a, well, custom component.
This is the code to dynamically render the tree
const renderDynamicComponents = (tree, components) =>
tree.map((item, index) => {
if (!item.component) return item;
const Comp = item.component;
const props = item.props ?? {};
if (!props?.key) {
throw new Error(
`Component is missing a unique 'key' for ${console.log(
JSON.stringify({ index, component: Comp })
)}`
);
}
if (item.children !== undefined) {
if (typeof item.children === "string") {
props.children = item.children;
} else if (Array.isArray(item.children)) {
props.children = renderDynamicComponents(item.children, components);
}
}
if (components?.[Comp] !== undefined) {
return createElement(components[Comp], props);
}
return createElement(Comp, props);
});
which sadly throws
Error: Cannot stringify a function
at walk ([..]/node_modules/devalue/dist/devalue.umd.js:29:20)
I thought I figured a solution by only running renderDynamicComponents
on the client, then I realized that that’s defeating the purpose of SSR tho 🤦🏻♂️
My problem
I don’t fully understand why this is happening, when I
// ..
props.children = renderDynamicComponents(item.children, components);
console.log(props.children);
// ..
I get:
{
'$$typeof': Symbol(react.element),
type: [Function: HeroComponent], <--- this is most probably the issue, right?
key: 'indexHero',
ref: null,
props: { className: 'bg-primary' },
_owner: null,
_store: {}
},
{
'$$typeof': Symbol(react.element),
type: 'h1',
key: 'indexH1',
ref: null,
props: { className: 'bg-red', children: 'H1' },
_owner: null,
_store: {}
}
Thought I’m smart again, for a split second, trying to HeroComponent.prototype.toString = () => "hero";
, though nothing 🥲
What can I do about this, what options do I have? The example JSON will be coming from my CMS, I thought about using MDX instead though I’d highly prefer less abstraction, as it’s machine handled and edited using the CMS’s UI anyway.
Please help 🥺
Issue Analytics
- State:
- Created 2 years ago
- Comments:13 (13 by maintainers)
Top GitHub Comments
Thanks 😃.
Have fun building 😉.
Let me have a look