SVG usa tag e ReactJS


114

Quindi normalmente per includere la maggior parte delle mie icone SVG che richiedono uno stile semplice, faccio:

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

Ora sto giocando con ReactJS negli ultimi tempi valutandolo come un possibile componente nel mio nuovo stack di sviluppo front-end, tuttavia ho notato che nella sua lista di tag / attributi supportati, né usexlink:hrefsono supportati.

È possibile usare sprite svg e caricarli in questo modo in ReactJS?


28
Per i futuri visitatori, ora puoi usare <use xlinkHref="/svg/svg-sprite#my-icon" />.
David Gilbertson

6
xlink:hrefè deprecato, ora dovrebbe usare solo href- developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
Matt Greer

2
@MattGreer A partire dal 2018, Safari ha ancora bisogno, xlink:hrefquindi dobbiamo ancora usarlo. Le applicazioni web effettive devono utilizzare il denominatore comune delle funzionalità del browser o implementare soluzioni alternative / polyfill specifici.
Tobia

Sto solo aggiungendo questo commento per aiutare gli altri che cercano questo errore, che è stato risolto dalla risposta di Jon Surrell di seguito:Property 'xlink' does not exist on type 'SVGProps<SVGImageElement>
Joe M

Risposte:


50

Aggiornamento settembre 2018 : questa soluzione è deprecata, leggi la risposta di Jon invece la .

-

React non supporta tutti i tag SVG come dici tu, c'è un elenco di tag supportati qui . Stanno lavorando su un supporto più ampio, ad esempio in questo ticket .

Una soluzione alternativa comune è iniettare HTML invece di tag non supportati, f.ex:

render: function() {
    var useTag = '<use xlink:href="https://stackoverflow.com/svg/svg-sprite#my-icon" />';
    return <svg dangerouslySetInnerHTML={{__html: useTag }} />;
}

19
No, non usare dangerouslySetInnerHTML. Puoi usare xlinkHrefcome indicato di seguito.
Tobia

L'autore dovrebbe probabilmente rimuoverlo come risposta accettata
Aquasar

267

MDN dice che xlink:href è deprecato a favore di href. Dovresti essere in grado di utilizzare l' hrefattributo direttamente. L'esempio seguente include entrambe le versioni.

A partire da React 0.14 , xlink:hrefè disponibile tramite React come proprietà xlinkHref. È menzionato come uno dei "miglioramenti notevoli" nelle note di rilascio per la 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>

Aggiornamento 2018-06-09: aggiunte informazioni sugli attributi hrefvs xlink:hrefed esempio aggiornato per includerli entrambi. Grazie @devuxer

Aggiornamento 3 : al momento della scrittura, le proprietà SVG master di React possono essere trovate qui .

Aggiornamento 2 : sembra che tutti gli attributi SVG dovrebbero ora essere disponibili tramite React (vedere PR attributi svg uniti ).

Aggiornamento 1 : potresti voler tenere d'occhio il problema relativo a svg su GitHub per l'atterraggio del supporto SVG aggiuntivo. Ci sono sviluppi nelle opere.

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>


2
> Aggiornamento 25 dicembre 2015: sembra che tutti gli attributi svg dovrebbero ora essere disponibili tramite reagire (vedere PR attributo svg unito). Esiste un modo standard per utilizzare questi attributi svg? Saranno tutti rivestiti di cammello come nel caso di xlink: href => xlinkHref?
majorBummer

@majorBummer dai un'occhiata qui
Jon Surrell

2
questa deve davvero essere la risposta corretta, specialmente quando la risposta attualmente scelta consiglia pericolosamenteSetInnerHTML, che è, beh, pericoloso
feihcsim

1
Secondo MDN ( developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href ), xlink:hrefè stato deprecato e si consiglia di utilizzare hrefsenza il prefisso dello spazio dei nomi. (Nota, tuttavia, se stai usando TypeScript, le digitazioni non sono state ancora aggiornate per riflettere questo.)
devuxer

Al momento della scrittura, xlink: href è supportato in Safari, ma href non lo è.
neoncube

7

Se incontri xlink:href, puoi ottenere l'equivalente in ReactJS rimuovendo i due punti e camelcasing il testo aggiunto:xlinkHref .

Probabilmente alla fine utilizzerai altri tag dello spazio dei nomi in SVG, come xml:space, ecc. La stessa regola si applica a loro (cioè xml:spacediventa xmlSpace).


6

Come già detto nella risposta di Jon Surrell, i tag use sono ora supportati. Se non stai usando JSX, puoi implementarlo in questo modo:

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

0

Ho creato un piccolo aiuto che risolve questo problema: https://www.npmjs.com/package/react-svg-use

prima npm i react-svg-use -Spoi semplicemente

import Icon from 'react-svg-use'

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

e questo genererà quindi il seguente markup

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

0

Gli SVG possono essere importati e utilizzati direttamente come componente React nel codice React.

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

const App = () => {
  return (
    <div className="App">
      <ReactIcon />
    </div>
  );
}
export default App;
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.