web-dev-qa-db-fra.com

Incorporation de SVG dans ReactJS

Est-il possible d'intégrer du balisage SVG dans un composant ReactJS?

render: function() {
  return (
    <span>
      <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmln ...
    </span>
  );
}

Résultats dans l'erreur:

Les attributs d'espace de noms ne sont pas pris en charge. ReactJSX n'est pas XML.

Quel est le moyen le plus léger de le faire. Utiliser quelque chose comme React ART , c'est exagéré pour ce que j'essaie de faire.

119
nicholas

Mise à jour 2016-05-27

À partir de React v15, la prise en charge de SVG dans React correspond (presque à?) À 100% avec la prise en charge actuelle du navigateur pour SVG ( source ). Vous devez simplement appliquer des transformations de syntaxe pour le rendre compatible JSX, comme vous devez déjà le faire pour HTML (classclassName, style="color: purple"style={{color: 'purple'}}). Pour tout attribut namespaced (séparé par des deux-points), par ex. xlink:href, supprimez le : et mettez en majuscule la deuxième partie de l'attribut, par exemple. xlinkHref. Voici un exemple de svg avec <defs>, <use> et les styles en ligne:

function SvgWithXlink (props) {
    return (
        <svg
            width="100%"
            height="100%"
            xmlns="http://www.w3.org/2000/svg"
            xmlnsXlink="http://www.w3.org/1999/xlink"
        >
            <style>
                { `.classA { fill:${props.fill} }` }
            </style>
            <defs>
                <g id="Port">
                    <circle style={{fill:'inherit'}} r="10"/>
                </g>
            </defs>

            <text y="15">black</text>
            <use x="70" y="10" xlinkHref="#Port" />
            <text y="35">{ props.fill }</text>
            <use x="70" y="30" xlinkHref="#Port" className="classA"/>
            <text y="55">blue</text>
            <use x="0" y="50" xlinkHref="#Port" style={{fill:'blue'}}/>
        </svg>
    );
}

Démonstration du code de travail

Pour plus de détails sur un support spécifique, consultez la documentation liste des attributs SVG supportés . Et voici le (maintenant fermé) numéro de GitHub qui suivait la prise en charge des attributs SVG avec espacement de noms.


Réponse précédente

Vous pouvez faire une simple intégration SVG sans avoir à utiliser dangerouslySetInnerHTML en supprimant simplement les attributs d'espace de nom. Par exemple, cela fonctionne:

        render: function() {
            return (
                <svg viewBox="0 0 120 120">
                    <circle cx="60" cy="60" r="50"/>
                </svg>
            );
        }

Vous pouvez alors ajouter des accessoires tels que fill, ou tout autre élément utile à configurer.

158
Andrew Patton

Si vous souhaitez simplement inclure une chaîne svg statique, vous pouvez utiliser dangerouslySetInnerHTML:

render: function() {
    return <span dangerouslySetInnerHTML={{__html: "<svg>...</svg>"}} />;
}

et React inclura directement le balisage sans le traiter du tout.

52
Sophie Alpert

Selon un développeur de réaction , vous n'avez pas besoin du xmlns d'espace de nom. Si vous avez besoin de l'attribut xlink:href, vous pouvez utiliser xlinkHref à partir de react 0.14

Exemple

Icon = (props) => {
  return <svg className="icon">
    <use xlinkHref={ '#' + props.name }></use>
  </svg>;
}
26
lastid

Si vous voulez le charger à partir d'un fichier, vous pouvez essayer d'utiliser React-inlinesvg - c'est assez simple et direct.

import SVG from 'react-inlinesvg';

<SVG
  src="/path/to/myfile.svg"
  preloader={<Loader />}
  onLoad={(src) => {
    myOnLoadHandler(src);
  }}
>
  Here's some optional content for browsers that don't support XHR or inline
  SVGs. You can use other React components here too. Here, I'll show you.
  <img src="/path/to/myfile.png" />
</SVG>
10
Youkko