web-dev-qa-db-fra.com

Comment importer de manière dynamique SVG et le rendre en ligne

J'ai une fonction qui prend des arguments et rend un SVG. Je souhaite importer de manière dynamique que SVG basé sur le nom transmis à la fonction. Cela ressemble à ceci:

import React from 'react';

export default async ({name, size = 16, color = '#000'}) => {
  const Icon = await import(/* webpackMode: "eager" */ `./icons/${name}.svg`);
  return <Icon width={size} height={size} fill={color} />;
};

Selon la Documentation WebPack pour les importations dynamiques et le commentaire magique "désireux":

"Génère pas de morceau supplémentaire. Tous les modules sont inclus dans le morceau actuel et aucune demande de réseau supplémentaire n'est faite. Une promesse est toujours renvoyée mais est déjà résolue. Contrairement à une importation statique, le module n'est pas exécuté tant que l'appel à l'importation () est fait."

C'est ce que mon icône est résolue à:

> Module
default: "static/media/antenna.11b95602.svg"
__esModule: true
Symbol(Symbol.toStringTag): "Module"

Essayer de le rendre comme ma fonction essaie de me donner cette erreur:

Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead.

Je ne comprends pas comment utiliser ce module importé pour le rendre comme un composant, ou est-ce même possible de cette façon?

9
Majoren

J'ai fait un changement basé sur la réponse https://github.com/facebook/create-react-app/issues/5276#issuecomment-66562839

export const Icon: FC<IconProps> = ({ name, ...rest }): JSX.Element | null => {
      const ImportedIconRef = useRef<FC<SVGProps<SVGSVGElement>> | any>();
      const [loading, setLoading] = React.useState(false);
      useEffect((): void => {
        setLoading(true);
        const importIcon = async (): Promise<void> => {
          try {
            // Changing this line works fine to me
            ImportedIconRef.current = (await import(`!!@svgr/webpack?-svgo,+titleProp,+ref!./${name}.svg`)).default;
          } catch (err) {
            throw err;
          } finally {
            setLoading(false);
          }
        };
        importIcon();
      }, [name]);

      if (!loading && ImportedIconRef.current) {
        const { current: ImportedIcon } = ImportedIconRef;
        return <ImportedIcon {...rest} />;
      }
      return null;
    };
1
Ariam 711