将SVG嵌入到ReactJS中


127

是否可以将SVG标记嵌入到ReactJS组件中?

render: function() {
  return (
    <span>
      <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmln ...
    </span>
  );
}

结果错误:

不支持命名空间属性。ReactJSX不是XML。

最简单的方法是这样做。使用React React之类的东西对于我想做的事情来说是过大的手段。


1
您可以创建一个jsbin吗?可能就像将您的SVG开头标签更改为“ just” <svg id="Layer_1">(甚至更好,没有id)一样简单。编辑:这是一个示例:jsbin.com/nifemuwi/2/edit?js,output
Brigand

@FakeRainBrigand谢谢!在这种情况下就是这么简单。看看本的答案。很高兴知道您可以在需要时进行jsx解析。
尼古拉斯

Answers:


178

更新2016-05-27

从React v15开始,React中对SVG的支持与当前浏览器对SVG的支持(接近?)达到100%奇偶校验()。您只需要应用一些语法转换就可以使其与JSX兼容,就像您已经对HTML所做的一样classclassNamestyle="color: purple"style={{color: 'purple'}})。对于任何命名空间(用冒号分隔)的属性,例如xlink:href,删除:并大写该属性的第二部分,例如xlinkHref。下面是与SVG的例子<defs><use>以及内嵌样式:

function SvgWithXlink (props) {
    return (
        <svg
            width="100%"
            height="100%"
            xmlns="http://www.w3.org/2000/svg"
            xmlnsXlink="http://www.w3.org/1999/xlink"
        >
            <style>
                { `.classA { fill:${props.fill} }` }
            </style>
            <defs>
                <g id="Port">
                    <circle style={{fill:'inherit'}} r="10"/>
                </g>
            </defs>

            <text y="15">black</text>
            <use x="70" y="10" xlinkHref="#Port" />
            <text y="35">{ props.fill }</text>
            <use x="70" y="30" xlinkHref="#Port" className="classA"/>
            <text y="55">blue</text>
            <use x="0" y="50" xlinkHref="#Port" style={{fill:'blue'}}/>
        </svg>
    );
}

工作码笔演示

有关特定支持的更多详细信息,请查看文档的支持的SVG属性列表。这是(现已关闭的)GitHub问题,该问题跟踪对命名空间SVG属性的支持。


先前的答案

您可以进行简单的SVG嵌入,而不必dangerouslySetInnerHTML通过剥离命名空间属性来使用。例如,这有效:

        render: function() {
            return (
                <svg viewBox="0 0 120 120">
                    <circle cx="60" cy="60" r="50"/>
                </svg>
            );
        }

此时,您可以考虑添加诸如之类的道具fill,或者其他可能对配置有用的道具。


@ChinonsoChukwuogor很好的问题!我不知道,我从未使用过React Native。你有去吗?
安德鲁·帕顿

@AndrewPatton带有打勾字符的多个Css类名称不起作用:' .class1, .class2{fill: #005baa;}'我该如何解决?
HelloWorld

@HelloWorld您能举个不起作用的例子吗?我只是添加了我的原始演示classB,但它起作用了:codepen.io/acusti/pen/BVJzNg
Andrew Patton

谢谢你,从此开始我已经成功地从文件导入SVG作为一个阵营成分没有任何装载机,我刚刚删除```的xmlns:OSB =“ openswatchbook.org/uri/2009/osb ”```从svg标记,仅保留xlmns。显然,所有这些都与标记解析有关。为以防万一,我已经按照这些步骤,以及:blog.logrocket.com/how-to-use-svgs-in-react
出资者

56

如果您只是想包含一个静态svg字符串,则可以使用dangerouslySetInnerHTML

render: function() {
    return <span dangerouslySetInnerHTML={{__html: "<svg>...</svg>"}} />;
}

React将直接包含标记而不进行任何处理。


3
我正在使用React控制SVG内部的某些路径,但是React似乎不支持滤镜元素。有没有办法支持这一点?似乎危险地SetInnerHTML无法正常工作,因为我无法在SVG内放置跨度,也无法使用它在路径上设置filter属性。我不认为可以像往常一样创建React元素,但是让它们逐字传递所有属性到DOM元素吗?
安迪

在2019年,您似乎可以使用危险地使用SetInnerHTML,但仍然无法使阴影滤镜在使用危险地使用SetInnerHTML的Chrome上运行,但它可以在Firefox上运行。
Shnd

31

根据React开发人员的说法,您不需要名称空间xmlns。如果需要该属性xlink:href,则可以使用react 0.14中的xlinkHref

Icon = (props) => {
  return <svg className="icon">
    <use xlinkHref={ '#' + props.name }></use>
  </svg>;
}

12

如果您想从文件中加载它,可以尝试使用React-inlinesvg-这非常简单明了。

import SVG from 'react-inlinesvg';

<SVG
  src="/path/to/myfile.svg"
  preloader={<Loader />}
  onLoad={(src) => {
    myOnLoadHandler(src);
  }}
>
  Here's some optional content for browsers that don't support XHR or inline
  SVGs. You can use other React components here too. Here, I'll show you.
  <img src="/path/to/myfile.png" />
</SVG>
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.