2014-05-01 57 views
74

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

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

导致错误:

Namespace attributes are not supported. ReactJSX is not XML.

什么是这样做的最轻的方式。使用诸如React ART之类的东西对于我正在尝试做的事情来说是过度杀伤力。

+1

你可以创建一个jsbin吗?这可能就像将开启的SVG标签改为''(甚至更好,没有id)一样简单。编辑:这里是一个例子:http://jsbin.com/nifemuwi/2/edit?js,output – FakeRainBrigand

+0

@FakeRainBrigand谢谢!在这种情况下就是这么简单。虽然,看看本的回答。很高兴知道您可以在需要时解决jsx解析问题。 – nicholas

回答

98

更新2016年5月27日

作为阵营V15,对SVG支持在阵营是(接近?)100%的奇偶校验与当前SVG浏览器支持(source)。您只需要应用一些语法转换来使其兼容JSX,即like you already have to do for HTMLclassclassName,style="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> 
    ); 
} 

Working codepen demo

有关特定支持的详细信息,请查看文档list of supported SVG attributes。这里是(现在关闭的)GitHub issue,它跟踪对命名空间SVG属性的支持。


以前的答案

你可以做一个简单的SVG嵌入,而无需通过只是剥离命名空间属性使用dangerouslySetInnerHTML。例如,这个工程:

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

此时你可以考虑增加道具像fill,或任何其他可能配置非常有用。

+1

React支持的SVG属性列表现在位于以下链接:https://facebook.github.io/react/docs/dom-elements.html#all-supported-svg-attributes –

+1

感谢galenlong,我更新了我的链接回答。 –

+0

这是否可以在ReactNative中使用? –

38

如果你只是要包括静态SVG字符串,可以使用dangerouslySetInnerHTML

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

并作出反应,将直接包括标记,而完全不处理它。

+1

我使用React控制SVG内部的一些路径,但React似乎不支持过滤元素。有没有办法支持这个?看起来像危险的SetInnerHTML不会工作,因为我不能在SVG中放置一个跨度,我不能使用它来设置路径上的过滤器属性。我不假设有像往常一样创建React元素的方法,但是让它们逐字地将所有属性传递给DOM元素? – Andy

25

According to a react developer,你不需要命名空间xmlns。如果你需要的属性xlink:href可以使用xlinkHref从反应0.14

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

这救了我的命。非常感谢! – stackyname

6

如果你想从文件加载它,你可以尝试使用React-inlinesvg - 这是非常简单和直接的。