SVG usa tag e ReactJS


114

Normalmente, para incluir a maioria dos meus ícones SVG que exigem um estilo simples, eu faço:

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

Agora estou brincando com ReactJS ultimamente, avaliando-o como um possível componente em minha nova pilha de desenvolvimento de front-end, no entanto, percebi que em sua lista de tags / atributos suportados, nem useou xlink:hrefsão suportados.

É possível usar sprites svg e carregá-los desta forma no ReactJS?


28
Para futuros visitantes, agora você pode usar <use xlinkHref="/svg/svg-sprite#my-icon" />.
— David Gilbertson de

6
xlink:hrefestá obsoleto, agora deve ser usado apenas href- developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
— Matt Greer

2
@MattGreer Em 2018, o Safari ainda precisa, xlink:hrefentão ainda precisamos usá-lo. Os aplicativos da web reais precisam usar o denominador comum dos recursos do navegador ou implementar soluções alternativas / polyfills específicos.
— Tobia

Estou apenas adicionando este comentário para ajudar outras pessoas que procuram esse erro, que foi resolvido pela resposta de Jon Surrell abaixo:Property 'xlink' does not exist on type 'SVGProps<SVGImageElement>
— Joe M

Respostas:


50

Atualização de setembro de 2018 : esta solução está obsoleta, leia a resposta de Jon .

-

O React não suporta todas as tags SVG, como você diz, há uma lista de tags suportadas aqui . Eles estão trabalhando em um suporte mais amplo, por exemplo, neste tíquete .

Uma solução alternativa comum é injetar HTML em vez de tags não suportadas, f.ex:

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

19
Não, não use dangerouslySetInnerHTML. Você pode usar xlinkHrefconforme mencionado abaixo.
— Tobia

O autor provavelmente deve remover esta como a resposta aceita
— Aquasar

267

MDN diz que xlink:href está obsoleto em favor de href. Você deve ser capaz de usar o hrefatributo diretamente. O exemplo abaixo inclui ambas as versões.

A partir do React 0.14 , xlink:hrefestá disponível via React como propriedade xlinkHref. É mencionado como um dos "aprimoramentos notáveis" nas notas de versão do 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>

Atualização 09/06/2018: informações adicionadas sobre atributos hrefvs xlink:hrefe exemplo atualizado para incluir ambos. Obrigado @devuxer

Atualização 3 : no momento em que este artigo foi escrito, as propriedades SVG master do React podem ser encontradas aqui .

Atualização 2 : Parece que todos os atributos svg devem agora estar disponíveis via react (consulte o atributo svg PR ).

Atualização 1 : você pode querer ficar de olho no problema relacionado ao svg no GitHub para obter suporte adicional a SVG. Há desenvolvimentos em andamento.

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
> Atualização em 25 de dezembro de 2015: Parece que todos os atributos svg agora devem estar disponíveis via react (consulte o atributo svg PR mesclado). Existe uma maneira padrão de usar esses atributos svg? Serão todos revestidos de camelo, como no caso de xlink: href => xlinkHref?
— majorBummer

@majorBummer, dê uma olhada aqui
— Jon Surrell

2
essa realmente precisa ser a resposta correta, especialmente quando a resposta atual escolhida recomenda
— hazouslySetInnerHTML

1
De acordo com o MDN ( developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href ), xlink:hreffoi preterido e a recomendação é usar hrefsem o prefixo de namespace. (Observe, no entanto, que se você estiver usando TypeScript, as tipificações ainda não foram atualizadas para refletir isso.)
— devuxer

No momento em que este artigo foi escrito, xlink: href era compatível com o Safari, mas href não.
— neoncube

7

Se você encontrar xlink:href, em seguida, você pode obter o equivalente em ReactJS através da remoção do cólon e camelcasing o texto acrescentou: xlinkHref.

Você provavelmente usará outras tags de namespace em SVG, como xml:space, etc. A mesma regra se aplica a eles (ou seja, xml:spacetorna-se xmlSpace).


6

Como já foi dito na resposta de Jon Surrell, use-tags agora. Se não estiver usando JSX, você pode implementá-lo assim:

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

0

Criei um pequeno ajudante que contorna esse problema: https://www.npmjs.com/package/react-svg-use

primeiro npm i react-svg-use -Sentão simplesmente

import Icon from 'react-svg-use'

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

e isso irá gerar a seguinte marcação

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

0

Os SVGs podem ser importados e usados ​​diretamente como um componente React em seu código React.

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

const App = () => {
  return (
    <div className="App">
      <ReactIcon />
    </div>
  );
}
export default App;
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.