genetic-orange
genetic-orange9mo ago

Maximum call stack size exceeded Circular Reference Error, nested custom menu

@kapa.ai Uncaught RangeError: Maximum call stack size exceeded. const { SubMenu } = Menu; const { useToken } = theme; export const ThemedSiderV2: React.FC<RefineThemedLayoutV2SiderProps> = ({ Title: TitleFromProps, render, Expand message.txt 9 KB @kapa.ai Uncaught RangeError: Maximum call stack size exceeded. This happen at children.length > 0 const RenderToTitle = TitleFromProps ?? TitleFromContext ?? ThemedTitleV2; const customMenuItems = [ { key: "parent", label: "Parent", route: "/parent", icon: <DashboardOutlined />, name: "parent", children: [ { key: "child", label: "Child", route: "/child", icon: <DashboardOutlined />, name: "child", children: [], }, ], }, ]; const renderTreeView = (tree: ITreeMenu[], selectedKey?: string) => { const mergedMenuItems = [...customMenuItems, ...tree]; return mergedMenuItems.map((item: ITreeMenu) => { const { icon, label, route, key, name, children, parentName, meta, options, } = item; if (children.length > 0) { return ( <CanAccess key={item.key} resource={name.toLowerCase()} action="list" params={{ resource: item, }} > <SubMenu key={item.key} icon={icon ?? <UnorderedListOutlined />} title={label} > {renderTreeView(children, selectedKey)} </SubMenu> </CanAccess> ); }
12 Replies
kapa.ai
kapa.ai9mo ago
Hi @lukevo.. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave: ---------------------- The error you're encountering, Uncaught RangeError: Maximum call stack size exceeded, typically occurs when there's a recursive function that doesn't have a proper termination condition, causing it to run indefinitely. In your case, the renderTreeView function is called recursively to render nested menu items. This function should stop calling itself when there are no more children to process. However, if there's a circular reference in your customMenuItems (i.e., a parent references a child, and that child references the parent), it could cause an infinite loop. Ensure that your customMenuItems data does not contain any circular references. Also, check that the children array for each item is defined and is an array. If children is undefined or not an array, it could potentially cause issues with the children.length > 0 check. Here's the relevant part of the code:
const renderTreeView = (tree: ITreeMenu[], selectedKey?: string) => {
const mergedMenuItems = [...customMenuItems, ...tree];

return mergedMenuItems.map((item: ITreeMenu) => {
const {
icon,
label,
route,
key,
name,
children,
parentName,
meta,
options,
} = item;

if (children.length > 0) {
return (
<CanAccess
key={item.key}
resource={name.toLowerCase()}
action="list"
params={{
resource: item,
}}
>
<SubMenu
key={item.key}
icon={icon ?? <UnorderedListOutlined />}
title={label}
>
{renderTreeView(children, selectedKey)}
</SubMenu>
</CanAccess>
);
}
// ...
});
};
const renderTreeView = (tree: ITreeMenu[], selectedKey?: string) => {
const mergedMenuItems = [...customMenuItems, ...tree];

return mergedMenuItems.map((item: ITreeMenu) => {
const {
icon,
label,
route,
key,
name,
children,
parentName,
meta,
options,
} = item;

if (children.length > 0) {
return (
<CanAccess
key={item.key}
resource={name.toLowerCase()}
action="list"
params={{
resource: item,
}}
>
<SubMenu
key={item.key}
icon={icon ?? <UnorderedListOutlined />}
title={label}
>
{renderTreeView(children, selectedKey)}
</SubMenu>
</CanAccess>
);
}
// ...
});
};
If you're still having trouble, you might want to consider simplifying your menu structure or using a different approach to render nested menu items. For more information on how to use the useMenu hook and render multi-level menus in Refine, you can refer to the Refine documentation (https://refine.dev/docs/api-reference/core/hooks/ui/useMenu/). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai9mo ago
<@582491401715974144> kapa.ai is still learning and improving, please let us know how it did by reacting below
genetic-orange
genetic-orange9mo ago
@kapa.ai @kapa.ai Uncaught RangeError: Maximum call stack size exceeded. const { SubMenu } = Menu; const { useToken } = theme; export const ThemedSiderV2: React.FC<RefineThemedLayoutV2SiderProps> = ({ Title: TitleFromProps, render, Expand message.txt 9 KB @kapa.ai Uncaught RangeError: Maximum call stack size exceeded. This happen at children.length > 0 const RenderToTitle = TitleFromProps ?? TitleFromContext ?? ThemedTitleV2; const customMenuItems = [ { key: "parent", label: "Parent", route: "/parent", icon: <DashboardOutlined />, name: "parent", children: [ { key: "child", label: "Child", route: "/child", icon: <DashboardOutlined />, name: "child", children: [], }, ], }, ]; const renderTreeView = (tree: ITreeMenu[], selectedKey?: string) => { const mergedMenuItems = [...customMenuItems, ...tree]; return mergedMenuItems.map((item: ITreeMenu) => { const { icon, label, route, key, name, children, parentName, meta, options, } = item; if (children.length > 0) { return ( <CanAccess key={item.key} resource={name.toLowerCase()} action="list" params={{ resource: item, }} > <SubMenu key={item.key} icon={icon ?? <UnorderedListOutlined />} title={label} > {renderTreeView(children, selectedKey)} </SubMenu> </CanAccess> ); } Look at my customMenuItems, it's correctly coded yea?
kapa.ai
kapa.ai9mo ago
Let me check the knowledge base for you. One moment! :books: ---------------------- Yes, your customMenuItems array appears to be correctly structured. It contains a parent item with a child item nested inside it. Here's the relevant part of your code:
const customMenuItems = [
{
key: "parent",
label: "Parent",
route: "/parent",
icon: <DashboardOutlined />,
name: "parent",
children: [
{
key: "child",
label: "Child",
route: "/child",
icon: <DashboardOutlined />,
name: "child",
children: [],
},
],
},
];
const customMenuItems = [
{
key: "parent",
label: "Parent",
route: "/parent",
icon: <DashboardOutlined />,
name: "parent",
children: [
{
key: "child",
label: "Child",
route: "/child",
icon: <DashboardOutlined />,
name: "child",
children: [],
},
],
},
];
Each item in the customMenuItems array is an object with properties like key, label, route, icon, name, and children. The children property is an array that can contain other menu items, allowing you to create nested menus. The renderTreeView function you've written is designed to handle this kind of nested structure. It uses recursion to render each item in the customMenuItems array, and if an item has children, it calls itself to render those children. However, the Uncaught RangeError: Maximum call stack size exceeded error typically indicates a problem with recursion. In this case, it might be caused by a problem elsewhere in your code, not in the customMenuItems array itself. If you're still having trouble, you might want to consider simplifying your menu structure or using a different approach to render nested menu items. For more information on how to use the useMenu hook and render multi-level menus in Refine, you can refer to the Refine documentation (https://refine.dev/docs/api-reference/core/hooks/ui/useMenu/). ---------------------- Note: you can ask me a follow up question by @ mentioning me again :speech_balloon: ----------------------
kapa.ai
kapa.ai9mo ago
<@582491401715974144> kapa.ai is still learning and improving, please let us know how it did by reacting below
stormy-gold
stormy-gold9mo ago
Hey @lukevo., I just look through the code Looks like you're appending customMenuItems to the array in every call of the renderTreeView but renderTreeView is recursive and causes an infinite loop Try merging the customMenuItems to the items while calling renderTreeView instead of inside of it.
genetic-orange
genetic-orange9mo ago
Hi there You're a god for helping me with this hahaha. Thank you so much Let me try How do I do that, which code to modify and where to move? Sorry for taking your time, I've only been learning react for 1 weke
stormy-gold
stormy-gold9mo ago
There should be a line in your code like:
const items = renderTreeView(menuItems, selectedKeys);
const items = renderTreeView(menuItems, selectedKeys);
you can update that one instead of the renderTreeView function
genetic-orange
genetic-orange9mo ago
const mergedMenuItems = [...customMenuItems, ...menuItems]; const items = renderTreeView(mergedMenuItems, selectedKey); I replaced that with these 2
stormy-gold
stormy-gold9mo ago
Nice, also need to remove the merge line in renderTreeView function
genetic-orange
genetic-orange9mo ago
Unfornutately nothing is showing This is where I console.log: // const items = renderTreeView(menuItems, selectedKey); const mergedMenuItems = [...customMenuItems, ...menuItems]; const items = renderTreeView(mergedMenuItems, selectedKey); console.log(items)
genetic-orange
genetic-orange9mo ago
@aliemirs