2016-08-29 2 views
2

我々は、window.onresizewindow.onscrollに、コンポーネント階層の異なる部分におけるDOM要素に関連するいくつかのアクションを実行する必要がありますReact.js - コンポーネントの階層の異なるレベルから使用DOM要素を

1)にリサイズする際の要素を移動しますモバイル解像度

2)スクロール時にクラスとスタイルを変更する。

問題は、要素がReactコンポーネント階層の異なるレベルにある、つまり異なるコンポーネントにネストされているということです。したがって、私が正しく理解すれば、refsを使用してDOMノードにアクセスすることはできません。

は私が持っている: {someCondition ? <FirstComponent/>: <SecondComponent/>}

someConditionのに対しては、原因ユーザーのUIアクションのいずれかに変更することができ、またはそれは、ページのロードの最初から真である可能性があります。

私は私のFirstComponentcomponentDidMountcomponentDidUpdateを使用してみましたが、componentDidMountのみ火災someCondition場合は最初から真実であることを発見した、とcomponentDidUpdateは確かに(コンポーネントに含まれている)ときsomeCondition変化したが、その後、必要なDOM要素を発射しますその時点では準備ができておらず、document.getElementByIdは失敗します。

追加すると、window.requestAnimationFrameが役に立たなかった

私はReactでこれを行うための強固な方法があると思いますか?

React.findDomNode

ありがとうございます。

+0

一般document.getElementById'は( 'React.findDOMNode'は通常、これを行う方法である'使用していますが、あなたが拡大することはできますか? 'ref'sを使用することができないについて何かを言及すべきではありませんそれ?) –

答えて

3

あなたが何を記述しているかは、リアクトのアンチテーゼです。これは、imperative jQuery/Dojoベースのフレームワークを使用するときに私が期待するアプローチです。

Reactでは、状態をレンダリングされたHTMLに変換する方法を知っている機能コンポーネントを開発しています。問題を別の方法で解決する必要があります。あなたの問題のために

、あなたのwindow.onresizewindow.onscrollコールバックはないが反応DOM要素を操作しようとする必要があります。代わりに、状態を更新してReactを再レンダリングさせるだけです。あなたのReactコンポーネントはこの状態を受け取り、それに従ってレンダリングする必要があります。

ここでは、メインアプリがこれらのイベントをリッスンし、状態を更新して再レンダリングをトリガーする簡単な例を示します。アプリは子供たちに小道具として州を渡します。子供たちは、条件付きでCSSクラス名を変更するために小道具を使います。彼らは簡単に別のHTMLやインラインスタイルをレンダリングすることもできます。

const Component2 = ({someCondition2}) => { 
    const className = someCondition2 ? "foo" : "bar"; 
    return <div className={className}>Hello</div>; 
}; 

const Component1 = ({someCondition1, someCondition2}) => { 
    const className = someCondition1 ? "A" : "B"; 
    return (
     <div className={className}> 
      <Component2 someCondition2={someCondition2} /> 
     </div> 
    ); 
}; 

class App extends React.Component { 
    state = { 
     someCondition: false, 
     someCondition2: true, 
    }; 

    componentDidMount() { 
     window.onresize = ev => { 
      const someCondition = ev.xxx; 
      // re-render with the new state 
      this.setState({ someCondition }); 
     }; 

     window.onscroll = ev => { 
      const someCondition2 = ev.xxx; 
      this.setState({ someCondition2 }); 
     }; 
    } 

    render() { 
     const {someCondition, someCondition2} = this.state; 
     return (
      <Component1 
       someCondition1={someCondition1} 
       someCondition2={someCondition2} /> 
     ); 
    } 
} 

React.render(<App />, document.getElementById("container")); 
+0

うーん。それは正しいと思うし、私が持っていた根本的な問題を解決する。私たちはReduxを使ってグローバルな状態を管理しており、スクロール中に複数のコンポーネントを操作する必要があります。これには、グローバルな状態を更新し、すべてのスクロールイベントでその変更に対応する必要があるため、パフォーマンスについて心配する必要がありますか? –

+0

「パフォーマンスについて懸念すべきか」に対する答えは、パフォーマンス上の問題に遭遇してこれに戻っていない限り、ほとんどの場合「そうではありません。ただそれを試してみてください。パフォーマンス上の問題が発生した場合、最初のステップとして、onscrollハンドラをスロットルまたはデバウンスして、それほど呼び出されないようにします。 – Brandon

関連する問題