SVG używa tagu i ReactJS

114

Więc zwykle, aby dołączyć większość moich ikon SVG, które wymagają prostej stylizacji, robię:

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

Teraz gram z ReactJS jak późno oceniając go jako ewentualny składnik mojego nowego frontonu stosie rozwoju jednak zauważyłem, że w swoim liście obsługiwanych tagów / atrybutów, ani useczy xlink:hrefsą obsługiwane.

Czy można używać sprite'ów svg i ładować je w ten sposób w ReactJS?

ryanzec
źródło
28
Dla przyszłych odwiedzających możesz teraz użyć <use xlinkHref="/svg/svg-sprite#my-icon" />.
David Gilbertson
6
xlink:hrefjest przestarzały, teraz powinien po prostu używać href- developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
Matt Greer
2
@MattGreer Od 2018 roku Safari nadal potrzebuje, xlink:hrefwięc nadal musimy go używać. Rzeczywiste aplikacje internetowe muszą albo używać wspólnego mianownika funkcji przeglądarki, albo implementować określone obejścia / wypełnienia.
Tobia
Po prostu dodaję ten komentarz, aby pomóc innym, którzy szukają tego błędu, który został rozwiązany przez odpowiedź Jona Surrella poniżej:Property 'xlink' does not exist on type 'SVGProps<SVGImageElement>
Joe M

Odpowiedzi:

50

Aktualizacja z września 2018 r . : to rozwiązanie jest przestarzałe, zamiast tego przeczytaj odpowiedź Jona .

-

React nie obsługuje wszystkie znaczniki SVG jak mówisz, jest lista obsługiwanych tagów tutaj . Pracują nad szerszym wsparciem, np. W tym zgłoszeniu .

Typowym obejściem jest wstawienie HTML zamiast nieobsługiwanych tagów, np .:

render: function() {
    var useTag = '<use xlink:href="https://stackoverflow.com/svg/svg-sprite#my-icon" />';
    return <svg dangerouslySetInnerHTML={{__html: useTag }} />;
}
David Hellsing
źródło
19
Nie, nie używaj dangerouslySetInnerHTML. Możesz użyć, xlinkHrefjak wspomniano poniżej.
Tobia
Autor powinien prawdopodobnie usunąć to jako zaakceptowaną odpowiedź
Aquasar
267

MDN twierdzi, że xlink:href jest to przestarzałe na korzyść href. Powinno być możliwe hrefbezpośrednie użycie atrybutu. Poniższy przykład obejmuje obie wersje.

Począwszy od React 0.14 , xlink:hrefjest dostępny za pośrednictwem React jako właściwość xlinkHref. Jest wymieniane jako jedno z „znaczących ulepszeń” w informacjach o wydaniu 0.14.

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

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

Aktualizacja 2018-06-09: Dodano informacje o atrybutach hrefvs xlink:hrefi zaktualizowano przykład, aby uwzględnić oba. Dzięki @devuxer

Aktualizacja 3 : W chwili pisania tego tekstu, właściwości SVG w React master można znaleźć tutaj .

Aktualizacja 2 : Wygląda na to, że wszystkie atrybuty svg powinny być teraz dostępne za pośrednictwem reakcji (patrz scalony atrybut svg PR ).

Aktualizacja 1 : Możesz mieć oko na problem związany z SVG na GitHub, aby uzyskać dodatkowe wsparcie dla SVG. Istnieją postępy w pracach.

Próbny:

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
źródło
2
> Aktualizacja 25 grudnia 2015 r .: Wygląda na to, że wszystkie atrybuty svg powinny być teraz dostępne za pośrednictwem reakcji (patrz scalony atrybut svg PR). Czy istnieje standardowy sposób używania tych atrybutów svg? Czy wszystkie będą w obudowie wielbłąda, jak w przypadku xlink: href => xlinkHref?
majorBummer
@majorBummer, spójrz tutaj
Jon Surrell
2
to naprawdę musi być prawidłowa odpowiedź, zwłaszcza gdy aktualnie wybrana odpowiedź zaleca niebezpiecznie
SetInnerHTML
1
Według MDN ( developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href ) xlink:hrefzostał wycofany, a zaleceniem jest używanie hrefbez przedrostka przestrzeni nazw. (Pamiętaj jednak, że jeśli używasz TypeScript, pisanie nie zostało jeszcze zaktualizowane, aby to odzwierciedlić.)
devuxer
W chwili pisania tego tekstu xlink: href jest obsługiwany w Safari, ale href nie.
neoncube
7

Jeśli napotkasz xlink:href, to można dostać równowartość w ReactJS poprzez usunięcie jelita grubego i camelCasing dodatkowy tekst: xlinkHref.

Prawdopodobnie w końcu będziesz używać innych znaczników przestrzeni nazw w SVG, takich jak xml:spaceitp. Ta sama reguła dotyczy ich (tj. xml:spaceStaje się xmlSpace).

HoldOffHunger
źródło
6

Jak już powiedziano w odpowiedzi Jona Surrella, tagi użycia są teraz obsługiwane. Jeśli nie używasz JSX, możesz to zaimplementować w następujący sposób:

React.DOM.svg( { className: 'my-svg' },
    React.createElement( 'use', { xlinkHref: '/svg/svg-sprite#my-icon' }, '' )
)
mhanisch
źródło
0

Stworzyłem małego pomocnika, który działa wokół tego problemu: https://www.npmjs.com/package/react-svg-use

najpierw npm i react-svg-use -Spo prostu

import Icon from 'react-svg-use'

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

a to wygeneruje następujący znacznik

<svg>
  <use xlink:href="#car" style="fill:#D71421;"></use>
</svg>
Ahrengot
źródło
0

Pliki SVG można importować i używać bezpośrednio jako komponent Reacta w kodzie React.

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

const App = () => {
  return (
    <div className="App">
      <ReactIcon />
    </div>
  );
}
export default App;
Olcay Özdemir
źródło