2015-12-26 16 views
7

たとえば、すべての米国州のパスを持つSVG要素があるとします。Reactを使用して対話型SVGコンポーネントを作成する

<svg> 
    <g id="nh"> 
     <title>New Hampshire</title> 
     <path d="m 880.79902,142.42476 0.869,-1.0765 1.09022,..." id="NH" class="state nh" /> 
    </g> 
    ... 
</svg> 

SVGデータは、別のファイル(.svg拡張子)に保存されます。私はいくつかの外部入力に基づいて個々の状態のスタイリングを変更できるように、そのマップのReactコンポーネントを完全に制御して作成したいとします。 raw-loaderを使用して、生のマークアップとして、それを挿入して、dangerouslySetInnerHTMLを使用してコンポーネントを作成します:

var InlineSvg = React.createClass({ 
    render() { 
    var svg = require('./' + this.props.name + '.svg'); 
    return <div dangerouslySetInnerHTML={{__html: svg}}></div>; 
    } 
}); 

または手動で変換WebPACKのを使用して

は、私の知る限り、私は、SVGマークアップをロードするための2つのオプションがあります有効なJSXへのマークアップ:

var NewComponent = React.createClass({ 
    render: function() { 
    return (
     <svg> 
      <g id="nh"> 
       <title>New Hampshire</title> 
       <path d="m 880.79902,142.42476 0.869,-1.0765 1.09022,..." id="NH" className="state nh" /> 
      </g> 
      ... 
     </svg> 
    ); 
}); 

最後に、のは、SVGマップに加え、すべての状態の簡単なHTMLのリストがありますと言ってみましょう。ユーザーがリスト項目の上を移動すると、対応するSVGパスが塗りつぶし色に移動します。

ここで私が把握できないのは、ホバリング状態を反映するためにReact SVGコンポーネントを更新する方法です。確かに、私はDOMに手を伸ばして、クラス名でSVG状態を選択し、その色を変えることができますが、それはそれを行う "反応する"方法ではないようです。指差し指は非常に高く評価されるだろう。

PS。私はコンポーネント間のすべての通信を処理するためにReduxを使用しています。

1)ハイライトされたアイテムのあなたのアプリに通知するために、各リスト項目にイベントリスナーを設定します。

答えて

3

あなたは二つのことを行う必要があります。

<li 
    onMouseOver={() => this.handleHover('NH')} 
    onMouseOut={() => this.handleUnhover()} 
> 
    New Hampshire 
</li> 

2)データをキャプチャし、それをSVGコンポーネントに伝播します。

これはより複雑な部分です。これは、アプリをどのように構造化したかになります。

  • あなたの全体のアプリケーションがコンポーネントを反応させる単一である場合、handleHoverは単にアプリが複数のコンポーネントに分割されている場合、handleHoverは支柱
として渡されたコールバックをトリガするコンポーネント状態
  • を更新するであろう

    後者を想定します。コンポーネントメソッドは次のようになります。

    handleHover(territory) { 
        this.props.onHighlight(territory); 
    } 
    
    handleUnhover() { 
        this.props.onHighlight(null); 
    } 
    

    あなたがSVGマップとリストの両方が含まれている親コンポーネントを、持っていると仮定すると、それは次のようになります。

    class MapWrapper extends React.Component { 
    
        constructor(props) { 
         super(props); 
         this.state = { 
          highlighted: null; 
         }; 
        } 
    
        setHighlight(territory) { 
         this.setState({ 
          highlighted: territory 
         }); 
        } 
    
        render() { 
         const highlighted = { this.state }; 
         return (
          <div> 
           <MapDiagram highlighted={highlighted} /> 
           <TerritoryList onHighlight={(terr) => this.setHighlight(terr)} /> 
          </div> 
         ); 
        } 
    
    } 
    
    は鍵がここにある

    highlighted状態変数。新しいホバーイベントが発生するたびに、highlightedの値が変更されます。この変更により、再レンダリングがトリガーされ、新しい値がに渡され、SVGのどの部分をハイライト表示するかを決定できます。

  • +0

    よろしくお願いいたします。しかし、1つのことは、 'setHighlight'の状態オブジェクトのキー' territory'は '強調表示される'でしょうか?つまり、元の状態オブジェクトのキー名と一致します。 –

    +0

    良い点。一定。 –

    +1

    「SVGへの伝播」の部分については、https://www.npmjs.com/package/react-samy-svgを作成しました。これにより、svg要素の属性のロードと操作が簡単になります。 –

    関連する問題