Home > Software design >  Render multiple SVG icons dynamically
Render multiple SVG icons dynamically

Time:12-08

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}/>;
  });
  • Related