将SVG标记添加到React组件

18

我正在尝试制作一个基于这个CodePen标记的React组件。

我的组件长这样:

import React from 'react';

class Arches extends React.Component {
    render(){
        return(/*markup from codepen*/);
    }
}

export default Arches;

但在渲染时它出现了问题:

unexpected token (764:3)
  762 |     d="m 46.842051,219.06796 

如何在React组件中正确地集成SVG?

1个回答

37

React支持SVG,但主要问题在于JSX与HTML不完全相同。您不能仅仅复制粘贴任何旧的HTML或SVG标记,并希望它在JSX中正常工作,而不需要一些清理。这个特定SVG片段的主要问题是:

  1. JSX不允许HTML风格的注释,例如您示例中的此注释:

<!-- Child Dentition -->

你需要完全删除这些,或者用 JSX Javascript-style comments 替换它们:

{/* Child Dentition */}
  • JSX不支持XML命名空间。所以像这样的命名空间元素将无法工作:

  • <metadata id="metadata8">
      <rdf:RDF>
        <cc:Work 
          rdf:about="">
          <dc:format>image/svg+xml</dc:format>
          <dc:type
             rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
          <dc:title>Human Dental Arches</dc:title>
        </cc:Work>
      </rdf:RDF>
    </metadata>
    
    事实上,如果您查看支持的SVG标签列表,甚至不包括metadata,因此可以直接删除此部分,因为它不会影响视觉输出。还要注意,像xml:space这样的命名空间属性也不起作用:
    <text xml:space="preserve" x="87.802124" y="124.42228" style="font-size:10.13467216px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#000000;fill-opacity:1;stroke:none;font-family:Sans">
    
    JSX使用className属性替代class。这是必要的,因为class是Javascript中的保留关键字,所以任何类似以下内容的代码:
    ```jsx
    ```
    在JSX中应该写作:
    ```jsx
    ```
    <path class="tooth-11 tooth-11-parent" />
    

    应该变成这样:

    <path className="tooth-11 tooth-11-parent" />
    
  • JSX中的style属性接受一个JavaScript对象,而不是字符串文字。所以像这样的值:

    <path style="fill:none;stroke:#000000;stroke-width:1;stroke-linecap:round;stroke-linejoin:miter;stroke-miterlimit:4;stroke-opacity:1;stroke-dasharray:none"/>
    

    需要被转换为:

    <path style={{fill: 'none', stroke: '#000000', strokeWidth: 1, strokeLinecap: 'round', strokeLinejoin: 'miter', strokeMiterlimit: 4, strokeOpacity: 1, strokeDasharray: 'none'}} />
    
  • 好的,这是很多变化!但是作为阅读到这里的奖励,我可以告诉您,有一种简单的方法可以实现大部分这些转换:这个页面 在React文档网站上允许您粘贴任意HTML片段并输出相应的JSX。似乎这个方法没有处理我上面提到的命名空间问题,但是经过一些手动修复,您可以得到一些有效的JSX,这将 很好地显示


    1
    链接的HTML到JSX编译器页面实际上并不能正常工作。粘贴带有命名空间属性的HTML会产生包含命名空间属性的JSX代码,在运行时将会出现错误。 - izk
    2
    @izk 没错,这在答案的最后一句话中被提到作为一个警告:“...这并没有解决我上面提到的命名空间问题...” - hopper

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接