【问题标题】:Load svg dinamically as a react component动态加载 svg 作为反应组件
【发布时间】:2017-07-07 08:36:51
【问题描述】:

我的应用应该呈现大约 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>
   )

}

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

【问题讨论】:

    标签: reactjs svg


    【解决方案1】:

    我向你推荐几件事:

    • 在单个组件中创建每个 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/

    如果您有任何问题,请告诉我。

    【讨论】:

    • 我正在使用 webpack。就是不知道怎么把3000万个svg组件集成到我的js代码中!
    猜你喜欢
    • 2019-08-13
    • 2022-07-19
    • 2019-05-03
    • 2018-07-31
    • 2020-10-10
    • 2018-03-17
    • 2021-08-13
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多