Search code examples
reactjsmaterial-uireact-functional-component

Component to call all material-ui Icon in React


I want to implement a component which calls the corresponding icon from material-ui. I've made it work when manually calling it.

import MenuIcon from '@material-ui/icons/Menu';
export const Icon = (props) => {
    return (
        <div>
            <MenuIcon/>
        </div>
    )
}

The problem is I don't know how to change the import for all icons. I want to call this component the following way:

<Icon icon="MenuIcon" className="someClass" />
<Icon icon="LocationOn" className="someClass" />
<Icon icon="Notifications" className="OthersomeClass" />

I can't figure out how to import all icons and how to change my Icon component to work for any icon from the material-ui package. Something like this...

import React from 'react';
import * as IconList from '@material-ui/icons/Menu'; //error

export const Icon = (props) => {
    const {icon, className} = props;
    return (
            <`${icon}` className={className} /> {//error}
    )
}

Any ideas?


Solution

  • You should be able to import all the icons using named imports or the star imports (* as).

    Star imports should look like this

    import * as Icons from "@material-ui/icons";
    
    <Icon icon={Icons.Menu} className="someClass" />
    <Icon icon={Icons.AccessAlarmIcon} className="someClass" />
    

    Named imports should look like this

    import { Menu, AccessAlarmIcon } from "@material-ui/icons";
    
    <Icon icon={Menu} className="someClass" />
    <Icon icon={AccessAlarmIcon} className="someClass" />
    

    You can also refactor your Icon component to utilize the React children prop, that way you can better compose each icon on the Icon component.

    So it should look something like this

    import React from 'react';
    
    export const Icon = ({ children }) => {
        return (
             <>{children}</>   
        )
    }
    

    Then you can use it like this

    <Icon>
      <Menu className="someClass" />
    </Icon>
    
    <Icon>
      <AccessAlarmIcon className="someClass" />
    </Icon>
    

    PS:

    Your star imports were from '@material-ui/icons/Menu' as opposed to just '@material-ui/icons' and that caused an error