【问题标题】:<svg> element string to React Component<svg> 元素字符串到 React 组件
【发布时间】:2019-04-21 07:09:55
【问题描述】:

嗨,我得到了一个带有图像 id 的房间对象,我获取并返回了以下内容

<svg id="Ebene_1" style={{"enableBackground":"new 0 0 32 32"}} version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" xmlSpace="preserve">
	<path d="M17.1,27h-10v-0.5c2.3,0,2.3-1,2.3-3.5h5.5c0,2.5,0,3.5,2.3,3.5V27z M30,6v20c0,0.6-0.4,1-1,1H18c-0.6,0-1-0.4-1-1v-4H3&#xD;&#xA;&#x9;c-0.6,0-1-0.4-1-1V9c0-0.6,0.4-1,1-1l14,0V6c0-0.6,0.4-1,1-1l11,0C29.6,5,30,5.4,30,6z M17,20h3v-9v-1h-1h-2H4v10H17z M24.8,22.5&#xD;&#xA;&#x9;c0-0.7-0.6-1.2-1.2-1.2s-1.2,0.6-1.2,1.2s0.6,1.2,1.2,1.2S24.8,23.2,24.8,22.5z M28,10h-6v1h6V10z M28,8h-7c0.6,0,1,0.4,1,1h6V8z"/>
</svg>

如果我如下手动将返回的字符串插入到反应组件中(添加宽度和高度),则该组件可以正常工作。

<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>


import React, { Component } from "react";

class LoxIcon extends Component{

    render(){
        return(
            <svg width ={'200'} height ={'200'}id= "Ebene_1" style={{"enableBackground":"new 0 0 32 32"}} version="1.1" viewBox="0 0 32 32" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" xmlSpace="preserve">
	                <path d="M17.1,27h-10v-0.5c2.3,0,2.3-1,2.3-3.5h5.5c0,2.5,0,3.5,2.3,3.5V27z M30,6v20c0,0.6-0.4,1-1,1H18c-0.6,0-1-0.4-1-1v-4H3&#xD;&#xA;&#x9;c-0.6,0-1-0.4-1-1V9c0-0.6,0.4-1,1-1l14,0V6c0-0.6,0.4-1,1-1l11,0C29.6,5,30,5.4,30,6z M17,20h3v-9v-1h-1h-2H4v10H17z M24.8,22.5&#xD;&#xA;&#x9;c0-0.7-0.6-1.2-1.2-1.2s-1.2,0.6-1.2,1.2s0.6,1.2,1.2,1.2S24.8,23.2,24.8,22.5z M28,10h-6v1h6V10z M28,8h-7c0.6,0,1,0.4,1,1h6V8z"/>
            </svg>
        )
    }
}  
export default LoxIcon;

鉴于这个元素是动态给我的,当我通过道具将数据传递给组件时,我该如何渲染它,比如

import React, { Component } from "react";

class LoxIcon extends Component{

    render(){
        return(
                {this.props.svg}
   }        
  }
}  
export default LoxIcon;
  

我尝试过 react-inlinesvg 和 reactSvg npm 模块,但都需要文件而不是字符串

【问题讨论】:

  • 您能分享一下您是如何将值传递给LoxIcon 的吗?
  • {(this.props.房间数据)? this.props.roomsData.map(room =>()) : null}

标签: javascript reactjs svg


【解决方案1】:

一种选择可能是将 svg 元素的 props 传递到您的组件中。如果您的动态元素并不总是 svg,您可以创建一些条件渲染来检查其是否为 svg 元素。

import React, { Component } from "react";

class LoxIcon extends Component{

    render(){
        return(
            <svg width={this.props.svg.width} height={this.props.svg.height} id={this.props.svg.id} style={this.props.svg.id} version={this.props.svg.id} viewBox={this.props.svg.viewBox} xmlns={this.props.svg.xmlns} x={this.props.svg.x} y={this.props.svg.y} xmlSpace={this.props.svg.xmlSpace}>
                    <path d={this.props.svg.d}/>
            </svg>
        )
    }
}  
export default LoxIcon;

【讨论】:

  • 我能明白你在说什么,但我没有通过道具传递 svg 的所有元素,我只是传递了一个字符串表示形式。 IE。 w3.org/2000/svg" x="0px" y ="0px" xmlSpace="preserve">
    你能把这些属性(id、style、viewBox...)从字符串中拉出来,然后作为道具传递吗?
  • 我认为这是我必须要做的,但是 dom 和元素字符串操作对我来说不是自然而然的 atm,但我们都知道任何指针都会有所帮助
  • 您可以使用 string.split() 方法来拆分字符串并循环查找属性。您可以传入诸如空格之类的字符(由于您的属性有诸如 viewBox 之类的空格,因此无法使用)或正则表达式来过滤掉您想要的内容。
【解决方案2】:

当您传递 html 的字符串表示形式时,您必须使用 dangerouslySetInnerHTML 设置内部 html 以设置 svg,尽管不建议这样做,因为它会暴露于跨站点脚本,因此您最好寻找其他替代方法,例如在 React 组件的渲染方法中将值设置为正确的 dom 表示。万一您想使用此方法,您可以尝试以下操作:

class LoxIcon extends Component {
    render() {
        return (<div dangerouslySetInnerHTML={{ __html: this.props.svg }} />);
       }
    }
export default LoxIcon;

您可以在dangerouslySetInnerHtmlhere上进一步阅读。

编辑:

正如 JP4 所建议的,您可以在 roomsData 数组的每个元素中创建 svg 对象,并将该对象作为道具传递给 LoxIcon,如 JP4 所回答.所以你的组件看起来像:

<Grid container className={classes.root} > 
    <Grid item > 
        <Grid container alignItems={'center'} justify="center" spacing={16}> 
        {(this.props.roomsData) ? this.props.roomsData.map(room => 
            (<Grid key={room.uuid} item > <Card > <LoxIcon svg={room.svgObject} /> </Card> </Grid>)) : null} 
        </Grid> 
    </Grid>
</Grid>

你的svgObject 应该是这样的:

{
    height: value,
    width: value.
.... followed by all the properties.
}

你的LoxIcon 会像

import React from 'react';

const LoxIcon = ({ svgObject }) => (<svg width ={svgObject.width} height ={svgObject.height} id={svgObject.id} ...{all the attributes of svgObject your want to set>
<path d={svgObject.path.d}/>
</svg>);

export default LoxIcon;

【讨论】:

  • 谢谢,我确实看到了 dangerouslySetInnerHTML 方法,但正如你所说,我拒绝了它。鉴于我收到的内容,即初始字符串,是否有足够的信息可以在 json 或 xml 中解析和操作它以生成 JP4 的道具,如果是这样,那么实现这一目标的最佳方法是什么
猜你喜欢
相关资源
最近更新 更多
热门标签