首页 文章

将svg作为反应组分加载

提问于
浏览
1

我的应用程序应该渲染大约30000个svg元素,具体取决于路由 . 如果路线像www.myapp.com/svg-data/person那么它应该渲染person.svg .

稍后(相同路线),可以修改此svg:添加背景颜色,某些文本或某些预定义图层 . 我想我应该加载svg作为反应组件 . 我正在看图书馆https://github.com/boopathi/react-svg-loader,但我认为这不符合我的目的 .

我最后的想法是将svg数据作为字符串获取并将其呈现在一个组件中,该组件返回svg等等...

我应该构建一个通用组件,它呈现作为参数的任何svg:

componentDidMount() {
    if (this.props.params.searchText) {
      this.props.requestSVG(this.props.params.searchText)
    }
  }

  componentWillReceiveProps(nextProps) {
    if (this.props.params.searchText !== nextProps.params.searchText) {
      this.props.requestSVG(nextProps.params.searchText)
    }
  }

该组件将呈现如下内容:

render() {
   const {svgData, textForSVGData} = this.props
   let svgText=null

   if (textForSVGData) {
     svgText= <text x='250' y='150' font-size='55'> {textForSVGData} </text>
   }

   return (
      <svg>
        {this.props.svgData}
        {svgText}
      </svg>
   )

}

根据道具,它应该根据需要添加文本或任何其他内容 . 我错过了什么吗?这是做这件事的好方法吗?

1 回答

  • 0

    我建议你,有几件事:

    • 在单个组件中创建每个SVG,这将帮助您隔离SVG的行为,样式,道具等

    • 使用higher order component创建通用组件,并将其用作代理,将动态道具传递给SVG组件,并在需要时添加常见的SVG行为

    • 关于路由器,您可以使用映射器Router-Icon或直接将SVG组件设置为要渲染的路由器组件

    SvgRendering 的主要目标是充当更高阶的组件,并使用给定的道具渲染给定的组件 .

    class SvgRenderer extends React.Component {
      constructor(props) {
        super(props);
    
        this.state = { invert: true };
        this.toggle = this.toggle.bind(this);
      }
    
      toggle() {
        this.setState({ inverted: !this.state.inverted });
      }
    
      render() {
        const { Svg, svgProps } = this.props;
        const { inverted } = this.state;
    
        return (
          <div>
            <button onClick={this.toggle}>toggle inverted svg</button>
            <div><Svg {...svgProps} inverted={inverted}/></div>
          </div>
        );
      }
    }
    

    同时 PlayIcon (SVG)的目标是设置自定义样式,文本,形状等 .

    const PlayIcon = (props) => {
      const { className, inverted } = props;
      const classes = className ? ['icon', 'logo', 'className'] : ['icon', 'logo'];
    
      if (inverted) classes.push('inverted');
    
      return (
        <div className={classes.join(' ')}>
          <svg
            version="1.1"
            viewBox="0 0 512 512">
            <path d="M256.000,512.000 C114.615,512.000 0.000,397.385 0.000,256.000 C0.000,114.615 114.615,0.000 256.000,0.000 C397.385,0.000 512.000,114.615 512.000,256.000 C512.000,397.385 397.385,512.000 256.000,512.000 ZM151.172,128.000 L151.172,384.000 L406.907,256.000 L151.172,128.000 Z" />
          </svg>
        </div>
      );
    };
    

    我对这个建议非常通用,并且我已经创建了这些建议的结果以及这个小提琴的实现示例:

    https://jsfiddle.net/69z2wepo/82451/

    如果您有任何疑问,请告诉我 .

相关问题