如何使用Webpack使用React内联多个SVG?

时间:2016-07-13 14:06:16

标签: svg reactjs webpack

假设我想要在我的React应用中内嵌一些或更多SVG。现在,我正在使用svg-react-loader像这样导入它们。

import Svg1 from "!babel!svg-react!../../images/sdg1.svg";
import Svg2 from "!babel!svg-react!../../images/sdg2.svg";
import Svg3 from "!babel!svg-react!../../images/sdg3.svg";
import Svg4 from "!babel!svg-react!../../images/sdg4.svg";

......等等。我需要在每个上面设置事件处理程序并悬停事件。此外,当选择其中一个时,我想改变它的不透明度。

经过几个小时以及尽可能多的失败实验,我唯一尝试过的方法就是将它们全部渲染到像这样的父组件中。

const Icon = React.createClass({

    //Callback that updates the state of a parent component
    clickHandler() {
        this.props.handler(this.props.svg) 
    }

    render() {

        const icons = [
            <Svg1 className="svg1" opacity={this.props.svg === this.props.currentSvg ? 1 : 0.3} />
            <Svg2 className="svg2" opacity={this.props.svg === this.props.currentSvg ? 1 : 0.3} />
            <Svg3 className="svg3" opacity={this.props.svg === this.props.currentSvg ? 1 : 0.3} />
            <Svg4 className="svg4" opacity={this.props.svg === this.props.currentSvg ? 1 : 0.3} />
        ];

        return (
            <div className="icon" onClick={this.clickHandler}>
                {icons[this.props.svg]}
            </div>
        );
    }    
});

同样,这有效,但我确信这不是React的意图。有没有办法迭代创建这种方式的SVG组件来分配它们的属性?

1 个答案:

答案 0 :(得分:2)

一种方法是将它们放在一个数组中并使用React.createElement

const icons = [Svg1, Svg2, Svg3, Svg4];

return (
    <div className="icon" onClick={this.clickHandler}>
        {icons.map((svg, i) => React.createElement(svg, {
            className: "svg"+i,
            opacity: (this.props.svg === this.props.currentSvg ? 1 : 0.3)
         })}
    </div>
);

另一个选择,因为您使用Webpack是为了使用他们的dynamic require功能。

基本上你可以给webpack一个文件的通配符来捆绑你的应用程序,然后在运行时动态地同步地要求它们:

// right below your import statements
const reqSvgs = require.context("../../images", false, /\.svg$/);

// now anywhere in your code you can:
const arrayOfSVGFilenames = reqSvgs.keys();
const specificSVG = reqSvgs("../../images/svg1.svg");
const allSVGsInAnArray = reqSvgs.keys().map(reqSvgs);