2017-09-01 10 views
1

汎用コンポーネントを作成しようとしています。他のアプリケーションで再利用できます。私はコンポーネントの内容を変更できるように、レンダリング後のコンポーネントの幅を知る必要があります。入手方法:実際にレンダリングした後のコンポーネントの幅

私は成功していない反応でさまざまなライフサイクルを使用しようとしてきました。

componentDidUpdate() { 
    console.log('width', this.element.offsetWidth); 
} 

render() { 
    return (
    <div ref={(element) => {this.element = element }} /> 
); 
} 

私はこれをしようとすると、私は、画面の幅を取得しますが、私は、ウィンドウのサイズを変更した場合、私は、コンポーネントの幅を取得します。クロームログを参照してください:

Chrome log

ComponentDidMountのでthis.elementundefinedあるレンダリングの前に実行されます。

私はまた、これをnpmから別のライブラリを使用して運がないまま解決しようとしました。

詳細情報:コンポーネントは、異なる幅でブートストラップカラム内で動作する必要があります。

render() { 
    <Row> 
    <Col sm={3} /> 
     <MyComponent /> 
    </Col> 
    <Col sm={9} /> 
     <MyComponent /> 
    </Col> 
    <Row> 
} 

明確化私は、ウィンドウのサイズを変更したくない、と私は明確にされていないことをお詫び申し上げます。私がサイズ変更について言及する唯一の理由は、DOMが作成されてサイズが変更されると、offsetWidthに正しい値が得られることです。私はサイズを変更せずに正しい値を取得するソリューションを探しています。ポストレンダリング関数呼び出し、リスナー、リアクションマジック、またはその他の解決策。私の問題は、バーチャルVSとリアルDOMの知識の欠如です。あなたはコンポーネントの幅状態を保持する必要がある場合は

+0

をレンダリングして、コンポーネントのサイズを変更するたびに、私は状態を設定した場合は、状態 – mersocarlin

+0

を更新するとき、次が生成されますどのannon関数setState({element:element})は無限ループを生成します。私はまた、その要素が 'null'最初に実行することを参照してください –

+0

私は状態に要素を格納するというよりもむしろ' width'値を格納すると言っていません。だから毎回それが変わります、あなたはあなたの状態価値を設定することができます。 – mersocarlin

答えて

1

私はここで与えられた答えでこの問題を解決することができませんでした。私はブラウザウィンドウの幅を持っていて、その中のコンポーネントはありません。いくつかの研究の後、私はレンダリングで鶏肉や卵の問題があるように見えます。もう少し研究を重ねた結果、私はこの問題を解決するreat-sizemeを見つけました。

import React, { Component } from 'react'; 
import sizeMe from 'react-sizeme'; 

class MyComponent extends Component { 
    render() { 
    const { width } = this.props.size; 

    return (
     <div style={{ 
     width: '100%', 
     backgroundColor: '#eee', 
     textAlign: 'center' 
     }}> 
     <span>My width is: {Math.floor(width)}px</span> 
     </div> 
    ); 
    } 
} 

export default sizeMe()(MyComponent); 

それは最初state` `でoffsetWidth``保存たぶん

enter image description here

1

あなたはこのような何かを行うことができます。

componentDidMount(){ 

      this.boundingBox = this.element.getBoundingClientRect(); 

      this.setState({ 
       width:this.boundingBox.width 
      }); 

      Observable.fromEvent(this.element,"resize") 
      .subscribe(
      () => { 
       this.boundingBox = this.element.getBoundingClientRect(); 
       this.setState({ 
        width:this.boundingBox.width 
       }); 
       } 
     ); 

};  

あなたはイベントリスナーで観察置き換えることができます。 また、クラスに添付されたバウンディングボックスを更新し、そこから状態を派生させることもできます。

componentDidUpdate(){ 
      this.boundingBox = this.element.getBoundingClientRect(); 
};  
+0

'componentDidMount'は' render'の前に実行されるので、this.elementは常に未定義です。提案? –

+0

レンダリング後に実行しません –

+0

docs:componentDidMount()は、コンポーネントがマウントされた直後に呼び出されます。 DOMノードを必要とする初期化はここに行かなければなりません。DOMノードはここで使用できます。使用することができます。投稿する前に答えをテストしてください。 –

0

これは直接あなたの質問への答えではないのに対し、それはあなたのコンポーネントの内部でサイズ変更や汚れたロジックを追加しませんあなたの問題への解決策です。

私はhttps://github.com/digidem/react-dimensionsのようなものをお勧めしたい - HOCラッパーで、グローバルリサイズイベントに耳を傾け、あなたの小道具を送信します - containerWidthcontainerHeightを - 私は、SVG、キャンバスやデータグリッドで作業する場合、それをたくさん使用する傾向がありますレスポンスのままにしておく必要があり、要素のサイズを知る必要があります。

ライフサイクルに関しては、componentDidUpdateのようなものは、あなたが思うように行動しないかもしれません。マウントは一回限りです。このコメントをお読みください - https://github.com/facebook/react/issues/2659#issuecomment-66165159

+0

私の質問に明確な更新があります。反応寸法は問題を解決しません。なぜなら、画面のサイズを変更してコンポーネントの幅を取得したくないからです。あなたのリンクをありがとう、私は今componentDidMountのより良い理解があります。 –

+0

あなたはそれをサイズ変更する必要はありません、それはあなたがマウントするとすぐにプロップを送信します。 –

関連する問題