2016-04-19 9 views
6

カプセル化を壊さずに次のようなことを行うためのカノニカルな方法はありますか? 反応カプセル化を破ることなくDOMにアクセス

import React, { Component, PropTypes } from 'react'; 

class Dashboard extends Component { 
    constructor(props, context) { 
     super(props, context); 

     this.setRef = ::this.setRef; 
    } 
    componentDidMount() { 
     const node = ReactDOM.findDOMNode(this.someRef); 
     const newHeight = window.innerHeight - node.offsetTop - 30; 
     node.style.maxHeight = `${newHeight}px`; 
    } 

    render() { 
     return (
      <div id="some-element-id" ref={this.setRef}> 
      </div> 
     ); 
    } 

    setRef(ref) { 
     this.someRef= ref; 
    } 
} 

ReactDOM.findDOMNode

はこれについて行くの提案方法のようですが、これはまだカプセル化を破壊し、ドキュメントがこの範囲に大きな赤い旗を持っています。

+0

「ブレークカプセル化」の意味を定義できますか?あなたの懸念事項は何ですか?高いレベルでは、あなたが正しいです、あなたはReactコンポーネント内のDOMを命令的に操作することに注意する必要がありますが、特にあなたの懸念事項は何ですか? –

+0

Reactはあなたから離れたDOMを抽象化するコンストラクトを提供し、あなたはDOMと対話するために非常に構築物の「外に出ています」 – Jordan

答えて

2

react要素のstyle propertyを設定するにはコンポーネント "state"を使用する必要があります。したがって、実際のDOMノードにアクセスして高さを計算し、状態を更新してコンポーネントを再描画します。リアクションコンポーネントは、実際のDOMノードと同じ情報を持つようになりました。カプセル化を破ってはいけません。

例を提供するために、バニラJSを使用した:

var Component = React.createClass({ 
    getInitialState: function(){ 
    return { 
     style: {}, 
    } 
    }, 
    componentDidMount: function(){ 
    var node = ReactDOM.findDOMNode(this); 
    var newHeight = window.innerHeight - node.offsetTop - 30; 
    this.setState({style: {backgroundColor: '#bbb', height: newHeight.toString() + 'px' }}); 
    }, 
    render: function(){ 
    return React.createElement('div', {style: this.state.style}, 'Height: ' + this.state.style.height); 
    }, 
}); 

あなたはそれがthis fiddleで実行して見ることができます。

+0

はい、私はそれについて考えていました - 良い点 – Jordan

+0

また、リアクションコンポーネントは実際のDOMノードと同じ情報を持っていますが、これはカプセル化を壊さないことを意味しているとはわかりません(特にここでも 'window'を使用しているので) - DOMノードが存在しているかどうかわかりませんコンポーネントを介して「安全に」公開されていますが、読み込み専用のDOMを使用し、コンポーネントの状態を同期させておけば、意図しない副作用からおそらく安全です – Jordan

+0

また、反応しているeslintプラグインを使用していて、ここでエラーが発生した場合は、実行中のことを知っている限り、無効にする必要があります。https://github.com/yannickcr/eslint-plugin-react/問題/ 554 – Jordan

2

これは技術的には一般的な意味で「カプセル化を破る」ものですが、それ以外の方法がない場合(この場合はありません)、findDOMNodeを使用することが唯一の選択であり、正しい方法です。

繰り返し使用している場合は、その動作をカプセル化するラッパーコンポーネントを作成する必要があります。

関連する問題