Використовуйте тег SVG та ReactJS


114

Тому зазвичай я включаю більшість моїх іконок SVG, для яких потрібна проста стилізація:

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

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

Чи можливо використовувати спрайти svg та завантажувати їх таким чином у ReactJS?


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тому нам ще потрібно його використовувати. Фактичним веб-додаткам потрібно або використовувати загальний знаменник функцій браузера, або впроваджувати конкретні обхідні шляхи / поліфауни.
Тобія

Я просто додаю цей коментар, щоб допомогти іншим, хто шукає цю помилку, яку вирішив відповідь Джона Суррелла нижче:Property 'xlink' does not exist on type 'SVGProps<SVGImageElement>
Джо М

Відповіді:


50

Оновлення вересня 2018 року : це рішення застаріле, замість цього прочитайте відповідь Йона .

-

Реагувати не підтримує всі теги SVG , як ви говорите, є список підтримуваних тегів тут . Вони працюють над широкою підтримкою, f.ex у цьому квитку .

Поширене рішення - ввести HTML замість непідтримуваних тегів, f.ex:

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

19
Ні, не використовуйте dangerouslySetInnerHTML. Ви можете використовувати, xlinkHrefяк зазначено нижче.
Тобія

Автор, мабуть, повинен видалити це як прийняту відповідь
Aquasar

267

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 дивіться тут
Джон Суррелл

2
це дійсно має бути правильною відповіддю, особливо коли поточна обрана відповідь рекомендує небезпечноSetInnerHTML, що, ну, небезпечно
feihcsim

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).


6

Як уже було сказано у відповіді Джона Суррелла, зараз використовуються теги use. Якщо ви не використовуєте 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;
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.