I’m new to React and I’m building my first headless WordPress site. I’m having trouble fetching submenus from my WordPress database for my React Bootstrap Navigation. The main menu items load fine. I’m using lodash groupby to try to organize the submenus under each parent. The dropdown parent label loads fine as well, but the sub items are empty. I’ve tried a lot of different things that haven’t worked. The main problem I’m having is mapping through the subItems. I get an error TypeError: subItems.map is not a function
If I change the subItems map to {Object.entries(subItems).map((subItem) => (
I don’t get the mapping error, but nothing is returned in the subItems and the console throws a warning:
Warning: Each child in a list should have a unique "key" prop.
I’ve gone down the rabbit hole on each error with no luck. Any guidance would be much appreciated. The code to my nav component is below:
import { Nav, NavDropdown } from "react-bootstrap";
import { client, MenuLocationEnum } from "client";
import _ from "lodash";
function MainNav({}): JSX.Element {
const { menuItems } = client.useQuery();
const links = menuItems({
where: { location: MenuLocationEnum.PRIMARY },
}).nodes;
const subItems = _.groupBy(
links.filter((link) => link.parentId),
"parentId"
);
return (
<Nav>
{links?.map((link) => {
let navItem;
if (subItems[link.id]) {
navItem = (
<NavDropdown title={link.label} key={link.id}>
{subItems?.map((subItem) => (
<NavDropdown.Item
href={subItem.url ?? ""}
key={subItem.id}
>
{subItem.label}
</NavDropdown.Item>
))}
</NavDropdown>
);
} else if (!link.parentId) {
navItem = (
<Nav.Link href={link.url ?? ""} key={link.id}>
{link.label}
</Nav.Link>
);
}
return navItem;
})}
</Nav>
);
}
export default MainNav;
Here’s what is being returned by my "subItems" group variable for one of the main nav items:
[
"cG9zdDo0Mw==",
[
{
"__typename": "MenuItem",
"id": "cG9zdDoxNDI=",
"parentId": "cG9zdDo0Mw==",
"url": "https://headless.site.app/sub-link-one/",
"label": "Sub Link One"
},
{
"__typename": "MenuItem",
"id": "cG9zdDoxNDM=",
"parentId": "cG9zdDo0Mw==",
"url": "https://headless.site.app/sub-link-two/",
"label": "Sub Link Two"
}
]
]
]
2
Answers
This might be a little messy, but it works. The top nav and sub nav items are now loading correctly. I had to dig my sub nav items out of the groupby obect by making it into an array, and then filter them by parentId to get to the proper place under the correct parent. Here's my solution:
In case anyone isn’t using Bootstrap, I thought this could be useful. This is what I used for my NextJS project: