SVG 使用标记和 ReactJS

因此,通常要包含大多数需要简单样式的 SVG 图标,我会这样做:

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

最近,我一直在使用 ReactJS,将它作为我新的前端开发堆栈中一个可能的组件,但是我注意到,在它支持的标记/属性列表中,既不支持 use,也不支持 xlink:href

有没有可能在 ReactJS 中使用 svg 精灵并以这种方式加载它们?

103754 次浏览

更新于2018年9月 : 此解决方案不适用,改为 Jon 的回答

--

React 并不像你说的那样支持所有的 SVG 标记,有一个支持标记 给你的列表。他们正致力于更广泛的支持,在 这张票的外汇交易。

一个常见的解决方案是注入 HTML,而不是不支持的标记,f.ex:

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

MDN 说 xlink:href 不推荐支持 href。您应该能够直接使用 href属性。下面的示例包括两个版本。

反应0.14开始,xlink:href可以作为属性 xlinkHref通过 React 获得。它被认为是 释放通知书 for 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: 增加了关于 hrefxlink:href属性的信息,并更新了包含这两个属性的示例

更新3 : 在编写本文时,React master SVG 属性可以找到 给你

更新2 : 似乎 所有 svg 属性现在应该可以通过 response 获得(参见合并的 属性公共关系)。

更新1 : 您可能需要关注 GitHub 上的 与 Svg 有关的问题以获得额外的 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>

我创建了一个小助手来解决这个问题: 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>

正如 Jon Surrell 在回答中已经说过的,现在支持 use-tag。如果您不使用 JSX,您可以这样实现它:

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

如果遇到 xlink:href,那么可以通过删除冒号并对添加的文本 xlinkHref进行骆驼化来获得 ReactJS 中的等价物。

您最终可能会在 SVG 中使用其他名称空间标记,比如 xml:space等等。同样的规则也适用于它们(例如,xml:space变成 xmlSpace)。

我有问题显示 SVG 在 Gutenberg 块,通过参考它与 xlink:href。我们使用 xlinkHref属性进行反应,但是在编译之后,我们将其呈现为 xlink:href,并将其呈现为 xlinkhref,而不显示 SVG。经过大量的研究,我发现 xlink:href是不推荐的(尽管如果我们在 html 中或直接在 chrome dev 工具中添加它,它是有效的) ,并且应该使用 href。所以把它改成 href之后就成功了。

“ SVG 2消除了对 xlink 名称空间的需要,因此应该使用 href 而不是 xlink: href。”

这是我用过的密码

SVG 文件

<svg id="svg-source" style="display: none;" aria-hidden="true" xmlns="http://www.w3.org/2000/svg">
<symbol id="svg-arrow-accordion" viewBox="0 0 15 24" fill="none">
<path id="Path_1662" data-name="Path 1662" d="M15.642,14.142h-3V1.5H0v-3H15.642Z" transform="translate(2 2) rotate(45)" fill="currentColor"></path>
</symbol>
</svg>

反应文件

<svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" width="15" height="24">
<use href="#svg-arrow-accordion"></use>
</svg>

这是 svg 组件。

const SvgComponent = () => {
return <svg width="0" height="0">
<defs>
<symbol id="test" viewBox="0 0 100 100">
<line x1='0' y1='50' x2='100' y2='50' strokeWidth='8' stroke="#000" />
</symbol>
</defs>
</svg>
}


export default SvgComponent

使用组件

import SvgComponent from './SvgComponent';


export default function App() {
return (
<>
<SvgComponent/>
<svg>
<use xlinkHref="#test"></use>
</svg>
</>
);
}