I'm using React with TypeScript and have 5 SVG icons in a directory that i can import like
import * as OtherIconsGroup from '../src/other-icons';
Then i can reference each icon like
<OtherIconsGroup.Loading fill={fillColor} width={size} height={size} />
<OtherIconsGroup.Like fill={fillColor} width={size} height={size} />
<OtherIconsGroup.Copy fill={fillColor} width={size} height={size} />
etc...
The problem now is that i need to add 30 icons to this directory and i'm looking for a way to dynamically render all components, something essentially like
{Object.keys(OtherIconsGroup).map(icon => {
return(
<OtherIconsGroup.{icon} fill={fillColor} width={size} height={size} />
)
}
This obviously doesn't work so i'm trying to understand how i can define a component, give it a custom name and return it.
{Object.keys(OtherIconsGroup).map(icon => {
const IconComponent = `OtherIconsGroup.${icon}`;
return(
<IconComponent fill={fillColor} width={size} height={size}/>
)
}
I'm getting the following error when adding the props above so looking for assistance on defining the component properly in TypeScript so i can add SVG element attributes.
Type '{ fill: string; width: number; height: number; }' is not assignable to type 'IntrinsicAttributes'.
Property 'fill' does not exist on type 'IntrinsicAttributes'.ts(2322)
CodePudding user response:
You are actually very close! Just minor syntax issues with JSX.
It could be done like this:
const icons = Object.entries(OtherIconsGroup)
.map(([_, Icon]) => <Icon fill={fillColor} width={size} height={size}/>);
or
const icons = Object.map(OtherIconsGroup)
.map((iconName) => {
const Icon = OtherIconsGroup[iconName];
return <Icon fill={fillColor} width={size} height={size}/>;
});