web-dev-qa-db-ja.com

Webpackを使用してReactコンポーネントにSVGを直接ロードするにはどうすればよいですか?

Webpackを使用して、NextButtonコンポーネントにマテリアルデザインアイコンを直接レンダリングしたいと思います。これが私のコードの関連部分です:

var NextIcon = require('material-design-icons/navigation/svg/production/ic_chevron_right_18px.svg');

var NextButton = React.createClass({
  render: function() {
    return (
      <Link to={this.props.target} className='button--next'>
        {this.props.label} {NextIcon}
      </Link>
    )
  }
});

しかし、これは私が思っていたようには機能していません。 svgを要素ではなく文字列として出力しているようです。

raw-loaderimg-loaderurl-loaderfile-loader、およびsvg-loaderを使用してみましたが、正しい方法が見つかりません。

10
dduupp

SVGコンテンツはReact要素としてではなく文字列として保存されるため、 Dangerously Set innerHTML を使用する必要があります。

var NextIcon = require('material-design-icons/navigation/svg/production/ic_chevron_right_18px.svg');

var NextButton = React.createClass({
  render: function() {
    return (
      <Link to={this.props.target} className='button--next'>
        {this.props.label} <span dangerouslySetInnerHTML={{ __html: NextIcon }} />
      </Link>
    )
  }
});

SVGファイルが必要なときに自動的にこれを行うWebpackローダーを作成することで、これを回避できる可能性があります。

dangerouslySetInnerHTML.loader.js

module.exports = function(content) {
    return (
        'module.exports = require("react").createElement("span", {' +
            'dangerouslySetInnerHTML: {' +
                '__html: ' + JSON.stringify(content) +
            '}' +
        '});'
    );
};

webpack.config.js

loaders: [
  {
    test: /\.svg$/,
    loader: require.resolve('./dangerouslySetInnerHTML.loader'),
    exclude: /node_modules/,
  },
],

前のコードスニペットは次のようになります。

var NextIcon = require('material-design-icons/navigation/svg/production/ic_chevron_right_18px.svg');

var NextButton = React.createClass({
  render: function() {
    return (
      <Link to={this.props.target} className='button--next'>
        {this.props.label} {NextIcon}
      </Link>
    )
  }
});
16