SVG verwendet Tag und ReactJS

114

Normalerweise mache ich Folgendes, um die meisten meiner SVG-Symbole einzuschließen, die ein einfaches Styling erfordern:

<svg>
    <use xlink:href="/svg/svg-sprite#my-icon" />
</svg>

Jetzt habe ich mit ReactJS gespielt, um es als mögliche Komponente in meinem neuen Front-End-Entwicklungsstapel zu bewerten. Ich habe jedoch festgestellt, dass in der Liste der unterstützten Tags / Attribute weder usenoch xlink:hrefunterstützt werden.

Ist es möglich, SVG-Sprites zu verwenden und auf diese Weise in ReactJS zu laden?

Ryanzec
quelle
28
Für zukünftige Besucher können Sie jetzt verwenden <use xlinkHref="/svg/svg-sprite#my-icon" />.
David Gilbertson
6
xlink:hrefist veraltet, soll jetzt nur verwenden href- developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
Matt Greer
2
@MattGreer Ab 2018 braucht Safari noch, xlink:hrefalso müssen wir es noch verwenden. Tatsächliche Webanwendungen müssen entweder den gemeinsamen Nenner der Browserfunktionen verwenden oder bestimmte Problemumgehungen / Polyfills implementieren.
Tobia
Ich füge nur diesen Kommentar hinzu, um anderen zu helfen, die nach diesem Fehler suchen, der durch Jon Surrells Antwort unten behoben wurde:Property 'xlink' does not exist on type 'SVGProps<SVGImageElement>
Joe M

Antworten:

50

Update September 2018 : Diese Lösung ist veraltet. Lesen Sie stattdessen Jons Antwort .

- -

Reagieren Sie nicht alle SVG - Tags unterstützt , wie Sie sagen, es gibt eine Liste der unterstützten Tags ist hier . Sie arbeiten an einer breiteren Unterstützung, z. B. in diesem Ticket .

Eine häufige Problemumgehung besteht darin, HTML für nicht unterstützte Tags einzufügen, z.

render: function() {
    var useTag = '<use xlink:href="https://stackoverflow.com/svg/svg-sprite#my-icon" />';
    return <svg dangerouslySetInnerHTML={{__html: useTag }} />;
}
David Hellsing
quelle
19
Nein, nicht benutzen dangerouslySetInnerHTML. Sie können xlinkHrefwie unten erwähnt verwenden.
Tobia
Der Autor sollte dies wahrscheinlich als akzeptierte Antwort entfernen
Aquasar
266

MDN sagt, dass dies zugunsten von xlink:href veraltet isthref . Sie sollten das hrefAttribut direkt verwenden können. Das folgende Beispiel enthält beide Versionen.

Ab 0,14 Reagieren , xlink:hrefist über Reagieren als Eigentum zur Verfügung xlinkHref. Es wird als eine der "bemerkenswerten Verbesserungen" in den Versionshinweisen für 0.14 erwähnt.

<!-- REACT JSX: -->
<svg>
  <use xlinkHref='/svg/svg-sprite#my-icon' />
</svg>

<!-- RENDERS AS: -->
<svg>
  <use xlink:href="/svg/svg-sprite#my-icon"></use>
</svg>

Update 2018-06-09: Informationen zu hrefvs- xlink:hrefAttributen hinzugefügt und Beispiel aktualisiert, um beide einzuschließen . Danke @devuxer

Update 3 : Zum Zeitpunkt des Schreibens finden Sie hier die SVG-Eigenschaften von React Master .

Update 2 : Es scheint, dass alle SVG-Attribute jetzt über "Reagieren" verfügbar sein sollten (siehe Zusammengeführtes SVG-Attribut PR ).

Update 1 : Möglicherweise möchten Sie das svg-bezogene Problem auf GitHub im Auge behalten, um zusätzliche SVG-Unterstützung zu erhalten. Es gibt Entwicklungen in den Arbeiten.

Demo:

const svgReactElement = (
  <svg
    viewBox="0 0 1340 667"
    width="100"
    height="100"
  >
    <image width="667" height="667" href="https://i.imgur.com/w7GCRPb.png"/>
    { /* Deprecated xlink:href usage */ }
    <image width="667" height="667" x="673" xlinkHref="https://i.imgur.com/w7GCRPb.png"/>
  </svg>
);

var resultHtml = ReactDOMServer.renderToStaticMarkup(svgReactElement);
document.getElementById('render-result-html').innerHTML = escapeHtml(resultHtml);

ReactDOM.render(svgReactElement, document.getElementById('render-result') );

function escapeHtml(unsafe) { return unsafe.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#039;"); }
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/16.4.1/umd/react.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.1/umd/react-dom.development.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/16.4.1/umd/react-dom-server.browser.development.js"></script>

<h2>Render result of rendering:</h2>
<pre>&lt;svg
  viewBox=&quot;0 0 1340 667&quot;
  width=&quot;100&quot;
  height=&quot;100&quot;
&gt;
  &lt;image width=&quot;667&quot; height=&quot;667&quot; href=&quot;https://i.imgur.com/w7GCRPb.png&quot;/&gt;
  { /* Deprecated xlink:href usage */ }
  &lt;image width=&quot;667&quot; height=&quot;667&quot; x=&quot;673&quot; xlinkHref=&quot;https://i.imgur.com/w7GCRPb.png&quot;/&gt;
&lt;/svg&gt;</pre>

<h2><code>ReactDOMServer.renderToStaticMarkup()</code> output:</h2>
<pre id="render-result-html"></pre>
<h2><code>ReactDOM.render()</code> output:</h2>
<div id="render-result"></div>

Jon Surrell
quelle
2
> Update 25. Dezember 2015: Es scheint, dass alle SVG-Attribute jetzt über "Reagieren" verfügbar sein sollten (siehe Zusammengeführtes SVG-Attribut PR). Gibt es eine Standardmethode zur Verwendung dieser SVG-Attribute? Werden sie alle wie im Fall von xlink: href => xlinkHref in Kamelhülle gehüllt?
MajorBummer
@majorBummer werfen Sie einen Blick hier
Jon Surrell
2
Dies muss wirklich die richtige Antwort sein, insbesondere wenn die aktuell gewählte Antwort gefährlich
SetInnerHTML
1
Laut MDN ( developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href ) xlink:hrefist es veraltet und es wird empfohlen, es hrefohne das Namespace-Präfix zu verwenden. (Beachten Sie jedoch, wenn Sie TypeScript verwenden, wurden die Eingaben noch nicht aktualisiert, um dies widerzuspiegeln.)
Devuxer
Zum Zeitpunkt des Schreibens wird xlink: href in Safari unterstützt, href jedoch nicht.
Neoncube
7

Wenn Sie auf etwas stoßen xlink:href, können Sie das Äquivalent in ReactJS erhalten, indem Sie den Doppelpunkt entfernen und den hinzugefügten Text mit einem Kamel versehen : xlinkHref.

Sie werden wahrscheinlich irgendwann andere Namespace-Tags in SVG verwenden, wie xml:spaceusw. Die gleiche Regel gilt für sie (dh xml:spacewird xmlSpace).

HoldOffHunger
quelle
6

Wie bereits in Jon Surrells Antwort erwähnt, werden Use-Tags jetzt unterstützt. Wenn Sie JSX nicht verwenden, können Sie es folgendermaßen implementieren:

React.DOM.svg( { className: 'my-svg' },
    React.createElement( 'use', { xlinkHref: '/svg/svg-sprite#my-icon' }, '' )
)
mhanisch
quelle
0

Ich habe einen kleinen Helfer erstellt, der dieses Problem umgeht : https://www.npmjs.com/package/react-svg-use

erst npm i react-svg-use -Sdann einfach

import Icon from 'react-svg-use'

React.createClass({
  render() {
    return (
      <Icon id='car' color='#D71421' />
    )
  }
})

Dadurch wird das folgende Markup generiert

<svg>
  <use xlink:href="#car" style="fill:#D71421;"></use>
</svg>
Ahrengot
quelle
0

SVGs können importiert und direkt als React-Komponente in Ihrem React-Code verwendet werden.

import React from 'react';
import {ReactComponent as ReactIcon} from './icon.svg';

const App = () => {
  return (
    <div className="App">
      <ReactIcon />
    </div>
  );
}
export default App;
Olcay Özdemir
quelle