De esta respuesta de stackoverflow, obtuve una solución sobre cómo importar svg como ReactComponent y cambiar su color/ancho, etc.
Pero, ¿es posible hacer lo mismo para la importación dinámica? Mi componente funcional:
import * as React from 'react'; import SvgIconComponent from './SvgIcon.Interface'; import {ReactComponent} from '*.svg'; const SvgIcon: React.FC<SvgIconComponent> =({width, color, name}) => { import(`../../assets/icons/${name}.svg`).then((Icon) => { return <Icon fill={color} width={width}/> }); }; export default SvgIcon;En la implementación actual obtengo errores:
TS2749: 'ReactComponent' refers to a value, but is being used as a type here. // .then((Icon as ReactComponent) TS2604: JSX element type 'Icon' does not have any construct or call signatures. // .then(Icon)Creo que es una mejor manera de usar el componente React para crear íconos dinámicos para el color y el ancho.
Agrego mi código de ejemplo:
export const TwitterIcon = ({color, width}: Props) => ( <svg width={width ? width : 24} height={width ? width : 24} viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg" > <path fill={color ? color : "#1f1f1f"} d="M8.0798 19.9998C9.55849 20.0493 11.0321 19.8018 12.4135 19.2721C13.795 18.7424 15.0562 17.9411 16.1227 16.9156C17.1892 15.8901 18.0393 14.6613 18.6228 13.3017C19.2063 11.9421 19.5113 10.4793 19.5198 8.9998C20.1974 8.16121 20.7006 7.19563 20.9998 6.1598C21.0221 6.07796 21.0203 5.99141 20.9946 5.91057C20.9689 5.82974 20.9203 5.75806 20.8548 5.70417C20.7893 5.65027 20.7096 5.61647 20.6253 5.60683C20.5411 5.59718 20.4558 5.6121 20.3798 5.6498C20.0253 5.82045 19.6262 5.87558 19.2386 5.80741C18.8511 5.73923 18.4948 5.5512 18.2198 5.2698C17.8687 4.88538 17.4441 4.57533 16.971 4.35803C16.498 4.14072 15.9861 4.02059 15.4657 4.00473C14.9454 3.98888 14.4272 4.07763 13.9417 4.26574C13.4563 4.45384 13.0136 4.73746 12.6398 5.0998C12.128 5.59546 11.7531 6.21509 11.5516 6.89847C11.3501 7.58186 11.3288 8.30575 11.4898 8.9998C8.1398 9.1998 5.8398 7.6098 3.9998 5.4298C3.94452 5.3672 3.87221 5.32205 3.7917 5.29987C3.71119 5.27769 3.62596 5.27943 3.54642 5.30488C3.46688 5.33033 3.39648 5.37839 3.3438 5.4432C3.29113 5.508 3.25846 5.58674 3.2498 5.6698C2.89927 7.61422 3.15213 9.61935 3.97442 11.4159C4.7967 13.2124 6.14904 14.7143 7.8498 15.7198C6.70943 17.0276 5.10801 17.8445 3.3798 17.9998C3.28721 18.0152 3.20174 18.0591 3.13535 18.1254C3.06896 18.1917 3.02497 18.2772 3.00954 18.3698C2.99411 18.4623 3.00801 18.5574 3.0493 18.6417C3.09059 18.726 3.15719 18.7952 3.2398 18.8398C4.74332 19.5912 6.39903 19.988 8.0798 19.9998Z" /> </svg> );Y si quieres hacer la biblioteca de iconos
interface IconProps { keyword: string; //make the clear type to make switch color: string; width: number; } const SvgIcon = ({keyword, color, width}: IconProps) => { // In this case you have to think about the switch and types in typescript. return ( { 'twitter': <TwitterIcon color={color} width={width}/>, 'facebook': <FacebookIcon color={color} width={width}/>, }[keyword] ) } //in component <SvgIcon keyword='twitter' width={24} color='red'/>Si tiene demasiados íconos SVG, no tengo ninguna solución en mis manos en este momento. Si tengo alguna buena idea con eso. Voy a publicar aquí de nuevo.
import MyIcon from '../../assets/icons/${name}.svg' <MyIcon />Por lo que puedo ver, su problema es que está importando todo el archivo y tratando de representarlo como un componente, debe agregar la clave/identificador del componente/nombre constante al requisito. Por ejemplo, si usa la exportación predeterminada YourSVGComponent, puede acceder a eso dinámicamente haciendo lo siguiente;
import * as React from 'react'; import SvgIconComponent from './SvgIcon.Interface'; const SvgIcon: React.FC<SvgIconComponent> =({width, color, name}) => { const Icon = require(`../../assets/icons/${name}.svg`).default return <Icon fill={color} width={width}/> }; export default SvgIcon;Le sugiero que utilice process.env.PUBLIC_URL para representar su svg. Tenga todos sus archivos svg dentro de una carpeta public , digamos dentro de public/svgFiles .
luego puede usarlo como <img src={process.env.PUBLIC_URL + "/svgFiles/" + file_name} alt="project" />
Dado que todo, desde la carpeta pública, se incluye en la build final, se cuidarán todos sus archivos svg, junto con la ruta que use, ya que todo se remitirá desde la carpeta pública, la ruta no se cambiará después de la compilación.