Search code examples
reactjstailwind-cssjsx

issue in rendering component elements (MAP)


please, if anyone can help, I have an issue rendering components elements in my sidebar using map. It's a React.jsx project with Tailwind CSS.

this is the sidebar.jsx :

import React, { useState } from "react";
import { menus } from "../data/sidebardata"; 

function Sidebar() {
   
    const [open, setOpen] = useState(false);

    return (
        <>
            <div className="h-screen w-full flex overflow-hidden select-none">
                <nav className={`w-24 flex flex-col items-center bg-white dark:bg-gray-800 py-4 ${open ? 'block' : 'hidden'}`}>
                    {menus.map((menu, index) => (
                        <li key={index} className="mt-3 p-2 hover:text-blue-600 dark-hover:text-blue-300 rounded-lg">
                            <a href={menu.link} className="flex flex-col items-center">
                                {menu.icon}
                                <span className="text-xs mt-2">{menu.name}</span>
                            </a>
                        </li>
                    ))}
                </nav>
                <button onClick={() => setOpen(!open)}>Toggle Sidebar</button>
            </div>
        </>
    );
}

export default Sidebar; 

AND this the sidebardata.js :

import GridViewOutlinedIcon from '@mui/icons-material/GridViewOutlined';

export const menus = [
    {
        name: "Notifications",
        link: "#",
        icon: GridViewOutlinedIcon,
    },
    
];

i need help please


Solution

  • Findings:

    Based on this documentation: https://mui.com/material-ui/icons/

    This is how you render the Icon {menu.icon}

    {menus.map((menu, index) => (
        <li key={index} className="mt-3 p-2 hover:text-blue-600 dark-hover:text-blue-300 rounded-lg">
            <a href={menu.link} className="flex flex-col items-center">
                {menu.icon}
                <span className="text-xs mt-2">{menu.name}</span>
            </a>
        </li>
    ))}
    

    And this is how you store your icon

    export const menus = [
        {
            name: "Notifications",
            link: "#",
            icon: GridViewOutlinedIcon,
        },
        
    ];
    

    Solution 1: to return ReactElement instead for your menu icon.

    export const menus = [
        {
            name: "Notifications",
            link: "#",
            icon: <GridViewOutlinedIcon />,
        },
        
    ];
    

    Solution 2: to use the menu.icon and instantiate the icon instead

    {menus.map((menu, index) => {
       const Icon = menu.icon;
    
       return (
        <li key={index} className="mt-3 p-2 hover:text-blue-600 dark-hover:text-blue-300 rounded-lg">
            <a href={menu.link} className="flex flex-col items-center">
                <Icon />
                <span className="text-xs mt-2">{menu.name}</span>
            </a>
        </li>
       )
    ))}
    

    You can choose either of the solution.