Тег использования SVG и ReactJS

115

Обычно, чтобы включить большинство моих значков SVG, требующих простого стиля, я делаю:

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

Сейчас я играю с ReactJS в последнее время его оценки в качестве возможного компонента в моем новом стеке развития фронтального однако я заметил , что в списке поддерживаемых тегов / атрибутов, ни useили xlink:hrefподдерживаются.

Можно ли использовать svg-спрайты и загружать их таким образом в ReactJS?

ryanzec
источник
28
Для будущих посетителей теперь можно использовать <use xlinkHref="/svg/svg-sprite#my-icon" />.
Дэвид Гилбертсон
6
xlink:hrefустарел, теперь предполагается просто использовать href- developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href
Мэтт Грир,
2
@MattGreer По состоянию на 2018 год Safari все еще нужен, xlink:hrefпоэтому нам все еще нужно его использовать. Реальные веб-приложения должны либо использовать общий знаменатель функций браузера, либо реализовывать определенные обходные пути / полифиллы.
Tobia
Я просто добавляю этот комментарий, чтобы помочь другим, кто ищет эту ошибку, которая была решена нижеприведенным ответом Джона Суррелла:Property 'xlink' does not exist on type 'SVGProps<SVGImageElement>
Джо М.

Ответы:

50

Обновление в сентябре 2018 года : это решение устарело, вместо этого прочтите ответ Джона .

-

Реагировать не поддерживает все теги SVG , как вы говорите, есть список поддерживаемых тегов здесь . Они работают над более широкой поддержкой, например, в этом тикете .

Распространенный обходной путь - вставить HTML вместо неподдерживаемых тегов, например:

render: function() {
    var useTag = '<use xlink:href="https://stackoverflow.com/svg/svg-sprite#my-icon" />';
    return <svg dangerouslySetInnerHTML={{__html: useTag }} />;
}
Дэвид Хеллсинг
источник
19
Нет, не используйте dangerouslySetInnerHTML. Вы можете использовать, xlinkHrefкак указано ниже.
Tobia
Автор, вероятно, должен удалить это как принятый ответ
Аквазар
268

MDN утверждает, что xlink:href это устаревшее решение в пользу href. Вы должны иметь возможность использовать hrefатрибут напрямую. Пример ниже включает обе версии.

Начиная с React 0.14 , xlink:hrefон доступен через React как свойство xlinkHref. Он упоминается как одно из «заметных улучшений» в примечаниях к выпуску 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>

Обновление 2018-06-09: добавлена ​​информация об атрибутах hrefvs xlink:hrefи обновлен пример, чтобы включить оба. Спасибо @devuxer

Обновление 3 : на момент написания, свойства SVG React master можно найти здесь .

Обновление 2 : похоже, что все атрибуты svg теперь должны быть доступны через реакцию (см. Объединенный атрибут svg PR ).

Обновление 1. Возможно, вы захотите следить за проблемой, связанной с svg, на GitHub, чтобы получить дополнительную поддержку SVG. Есть разработки в работе.

Демо:

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
> Обновление 25 декабря 2015 года: похоже, что все атрибуты svg теперь должны быть доступны через реакцию (см. Объединенный атрибут svg PR). Есть ли стандартный способ использования этих атрибутов svg? Будут ли они все в верблюжьем корпусе, как в случае с xlink: href => xlinkHref?
MajorBummer
@majorBummer, взгляните сюда
Джон Суррелл
2
это действительно должен быть правильный ответ, особенно когда текущий выбранный ответ рекомендует
feihcsim 02
1
Согласно MDN ( developer.mozilla.org/en-US/docs/Web/SVG/Attribute/xlink:href ) xlink:hrefустарел, и рекомендуется использовать hrefбез префикса пространства имен. (Обратите внимание, однако, если вы используете TypeScript, типизация еще не обновлена, чтобы отразить это.)
devuxer
На момент написания xlink: href поддерживается в Safari, а href - нет.
neoncube
7

Если вы столкнулись xlink:href, то вы можете получить эквивалент в ReactJS пути удаления толстого кишечника и camelcasing добавленного текста: xlinkHref.

Вы, вероятно, в конечном итоге будете использовать другие теги пространства имен в SVG, например xml:space, и т. Д. То же правило применяется к ним (т.е. xml:spaceстановится xmlSpace).

HoldOffHunger
источник
6

Как уже было сказано в ответе Джона Суррелла, теперь поддерживаются теги использования. Если вы не используете JSX, вы можете реализовать это следующим образом:

React.DOM.svg( { className: 'my-svg' },
    React.createElement( 'use', { xlinkHref: '/svg/svg-sprite#my-icon' }, '' )
)
Маниш
источник
0

Я создал небольшого помощника, который помогает решить эту проблему: https://www.npmjs.com/package/react-svg-use

сначала npm i react-svg-use -Sтогда просто

import Icon from 'react-svg-use'

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

и тогда будет создана следующая разметка

<svg>
  <use xlink:href="#car" style="fill:#D71421;"></use>
</svg>
Аренгот
источник
0

SVG можно импортировать и использовать непосредственно как компонент React в вашем коде React.

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

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

Олчай Оздемир
источник