Etiqueta de uso SVG y ReactJS


114

Entonces, normalmente para incluir la mayoría de mis íconos SVG que requieren un estilo simple, lo hago:

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

Ahora he estado jugando con ReactJS en los últimos tiempos la evaluación como un posible componente en mi nueva pila de desarrollo front-end sin embargo, me di cuenta de que en su lista de etiquetas / atributos soportados, ni useo xlink:hrefson compatibles.

¿Es posible usar sprites svg y cargarlos de esta manera en ReactJS?


28
Para futuros visitantes, ahora puede usar <use xlinkHref="/svg/svg-sprite#my-icon" />.
— David Gilbertson

6
xlink:hrefestá en desuso, ahora se supone que solo debe usar href- developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
— Matt Greer

2
@MattGreer A partir de 2018, Safari aún lo necesita, xlink:hrefpor lo que aún necesitamos usarlo. Las aplicaciones web reales deben utilizar el denominador común de las funciones del navegador o implementar soluciones / polyfills específicos.
— Tobia

Solo estoy agregando este comentario para ayudar a otros que buscan este error, que fue resuelto por la respuesta de Jon Surrell a continuación:Property 'xlink' does not exist on type 'SVGProps<SVGImageElement>
— Joe M

Respuestas:


50

Actualización de septiembre de 2018 : esta solución está obsoleta, lea la respuesta de Jon en su lugar.

-

React no admite todas las etiquetas SVG como usted dice, hay una lista de etiquetas compatibles aquí . Están trabajando en un soporte más amplio, p. Ej. En este ticket .

Una solución alternativa común es inyectar HTML en lugar de etiquetas no compatibles, f.ex:

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

19
No, no lo use dangerouslySetInnerHTML. Puede utilizar xlinkHrefcomo se menciona a continuación.
— Tobia

El autor probablemente debería eliminar esto como la respuesta aceptada
— Aquasar

267

MDN dice que xlink:href está en desuso a favor de href. Debería poder utilizar el hrefatributo directamente. El siguiente ejemplo incluye ambas versiones.

A partir de React 0.14 , xlink:hrefestá disponible a través de React como propiedad xlinkHref. Se menciona como una de las "mejoras notables" en las notas de la versión de 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>

Actualización 2018-06-09: se agregó información sobre los atributos hrefvs xlink:hrefy un ejemplo actualizado para incluir ambos. Gracias @devuxer

Actualización 3 : En el momento de escribir este artículo, las propiedades de React master SVG se pueden encontrar aquí .

Actualización 2 : Parece que todos los atributos svg ahora deberían estar disponibles a través de react (ver PR del atributo svg fusionado ).

Actualización 1 : es posible que desee estar atento al problema relacionado con svg en GitHub para obtener más compatibilidad con SVG. Hay novedades en proceso.

Manifestación:

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
> Actualización 25 de diciembre de 2015: parece que todos los atributos svg ahora deberían estar disponibles a través de react (ver PR del atributo svg fusionado). ¿Existe una forma estándar de utilizar estos atributos svg? ¿Serán todos en caja de camello como en el caso de xlink: href => xlinkHref?
— majorBummer

@majorBummer echa un vistazo aquí
— Jon Surrell

2
esta realmente debe ser la respuesta correcta, especialmente cuando la respuesta elegida actual recomienda dangerouslySetInnerHTML, que es, bueno, peligroso
— feihcsim

1
Según MDN ( developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href ), xlink:hrefha quedado obsoleto y la recomendación es utilizarlo hrefsin el prefijo de espacio de nombres. (Nótese, sin embargo, si usted está utilizando mecanografiado, las tipificaciones todavía no se han actualizado para reflejar esto.)
— devuxer

En el momento de escribir este artículo, xlink: href es compatible con Safari, pero href no.
— neoncube

7

Si se encuentra xlink:href, entonces se puede obtener el equivalente en ReactJS por la extirpación del colon y camelCasing el texto añadido: xlinkHref.

Probablemente eventualmente usará otras etiquetas de espacio de nombres en SVG, como xml:space, etc. La misma regla se aplica a ellos (es decir, se xml:spaceconvierte en xmlSpace).


6

Como ya se dijo en la respuesta de Jon Surrell, las etiquetas de uso ahora son compatibles. Si no está utilizando JSX, puede implementarlo así:

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

0

Creé un pequeño ayudante que soluciona este problema: https://www.npmjs.com/package/react-svg-use

primero npm i react-svg-use -Sluego simplemente

import Icon from 'react-svg-use'

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

y esto generará el siguiente marcado

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

0

Los SVG se pueden importar y usar directamente como un componente de React en su código de React.

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

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

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.