ok guys I have a problem.
I need render a list which has a title and a icon . and I Want to render it dynamic with map method.
This is the backend api object(Its more than 2 :D )
// icons are Material UI Icon component
const list = [
{title: 'Vehicle', icon: 'DirectionsCarFilledOutlined'},
{title: 'Electronic', icon: 'PhoneIphoneOutlined'},
]
What I have to do is to render this icon COMPONENT
dynamic
something like this
import {
DirectionsCarFilledOutlined,
PhoneIphoneOutlined,
} from "@mui/icons-material";
const list = [
{title: 'Vehicle', icon: 'DirectionsCarFilledOutlined'},
{title: 'Electronic', icon: 'PhoneIphoneOutlined'},
]
{list.map(({ title, icon }) => {
return (
<div>
<p>{title}</p>
<div>{<icon />}</div> // Problem is here. IDK How to render it
</div>
);
})}
I Wrote switch case for this problem but that's bad and if we add new items to api those lists won't have icon.
Is there anyway to render this Icons dynamic ?
CodePudding user response:
You can solve your problem by using React.lazy
to LazyLoad icons, given that the icon value corresponds to an exact path from @mui/icons-material
.
To do so, first we need to define a lazy function that can return non-default exports, since React.lazy
expects to return a default import
// iconName is still undefined, but we'll get to it
const Icon = lazy(() =>
import("@mui/icons-material").then(module => ({ default: module[iconName] }))
);
Then, we'll write an Item component, which receives iconName as a prop and LazyLoads it, utilizing React.Suspense
to allow for the component to be rendered.
import React, {lazy, Suspense} from 'react'
const Item = ({title, iconName}) => {
const Icon = lazy(() =>
import("@mui/icons-material").then(module => ({ default: module[iconName] }))
);
return (
<div>
<p>{title}</p>
<div>
<Suspense fallback={<></>}>
<Icon/>
</Suspense>
</div>
</div>
)
}
You should then import Item
inside your component and return Items from your map.
CodePudding user response:
Hope this could be the solution for you.
You can directly set the icon element
imported from @mui/icons-material
as the value of the icon
of the list
item.
import {
DirectionsCarFilledOutlined,
PhoneIphoneOutlined,
} from "@mui/icons-material";
const list = [
{title: 'Vehicle', icon: DirectionsCarFilledOutlined},
{title: 'Electronic', icon: PhoneIphoneOutlined},
]
... in render part
{list.map(({ title, icon }) => {
return (
<div>
<p>{title}</p>
<div><icon /></div> // Problem is here. IDK How to render it
</div>
);
})}