2016-08-11 90 views
2

私はReactにかなり新しいです。子コンポーネントが互いに通信するためのきれいな方法を理解しようとしています。Reactの子コンポーネントは、きれいで保守しやすい方法で互いに通信する必要がありますか?

単純なコンポーネントでは、子にデータを渡すために小道具を使用し、子コンポーネントが親コンポーネントにデータを戻すためのコールバックを使用できることはわかっています。 enter image description here

親コンポーネントに複数の子コンポーネントがある場合、子コンポーネント間の通信は少し混乱します。お互いにコミュニケーションするために、同じレベルの子どもたちのコンポーネントのために何をすべきかわかりません。 enter image description here

私の場合、私はおそらくstatesを使うことができると決めました。だから私は親コンポーネントにstateの値を持ち、それを子供の小道具に渡します。同様に、親コンポーネント内のコールバックハンドラ(childrenコンポーネントから呼び出される)は、状態値をReactのバインディングを介してある子供から別の子に渡すように状態を設定するのに役立ちます。

enter image description hereと擬似コードのようなものになります。この時点で

//Inside Parent Component 
constructor() { 
    //initialise state for the child components 
    this.setState({testList: []}); 
} 

render() { 
    return (
     <div> 
      <ChildA onSomething={this.onSomethingHandler} testList={this.state.testList} /> 
      <ChildB onSomethingElse={this.onSomethingElseHandler} testList={this.state.testList} /> 
     </div> 
    ); 
} 

onSomethingHandler(evt):void { 
    if(blah.blah.blah) this.setState({testList: this.state.testList.splice().push(evt.value)}; 
} 

onSomethingElseHandler(evt):void { 
    //Some other complex biz logic... 
    if(blah.blah.blah) this.setState({testList: this.state.testList.splice().push(somethingOtherStuffDueToLogic)}; 
} 

//Inside ChildA Component 
export IChildAProps { 
    onSomething: (evt)=>void 
} 

render() { 
    //Do some logic from the value in testList property 
    if(this.state.testList == blah blah)... 

    return (
     <button onClick={this.props.onSomething({id:321, value:"wassup! I'm ChildA."})}>ChildA</button> 
    ) 
} 

//Inside ChildB Component 
export IChildBProps { 
    onSomethingElse: (evt)=>void 
} 

render() { 
    //Do some logic from the value in testList property 
    if(this.state.testList == blah blah)... 

    return (
     <button onClick={this.props.onSomething({id:123, value:"yo! I'm ChildB."})}>ChildB</button> 
    ) 
} 

を、私は疑問に思い始めている場合は、親コンポーネントで、すなわちonSomethingHandler()onSomethingElseHandler()その2ハンドラメソッド、内のロジック、子コンポーネント自体の内部に実際に存在するはずですか?私はこれを考えました。なぜなら、それらのロジックは、子コンポーネントが自分の目的に役立てるために自分で処理しなければならないもののように見えるからです。親コンポーネントはそれらのためにそれを行うべきではありません、またはちょうど乱雑に成長するかもしれません。しかし、私は彼らのコミュニケーションをどのように扱っているかのために選択肢がありません。これとは別に、私は単にコミュニケーションできるように新しい状態を作成しました。

これまでのところ、これはまだ比較的管理しやすいです。しかし、私自身の実験では、同じ(あるいは時々異なる)レベルの他の子コンポーネントを介して通信する必要がある、別の子コンポーネント内に子コンポーネントがネストされている段階に達しています。コミュニケーションのための州を使用することはまた私に多くの州を持っていることを意味し、それは私には良いアイデアのようには見えません。そして、親コンポーネントは、コンポーネントツリーの上下にあるすべてのデータの伝播を管理するために、数多くの面倒なコールバックハンドラメソッドで終了しました。

状況は、私が高々そうのようなものとして、それを説明することができるように厄介です: enter image description here

そして、あなたは上の図で見ることができ、ChildBはちょうど間にその情報を渡すことを助けるためにさらに別の状態を持つことになりました子コンポーネントです。

私はReactについて知っておくべきことが何か不足していると確信しています。私が親コンポーネントで持っているコールバックは、ちょうどデータ伝播を処理するのにはあまりにも多すぎるようです。どのように私は本当にきれいで維持しやすい方法で子どもたちのコンポーネントのコミュニケーションを整理する必要がありますか?

+0

私が正しくあなたを理解していれば、あなたは親から共有リソース( 'testList')を渡していますすべての子供に。私は管理と制御/同期が難しく、何らかの理由でこの 'testList'のインスタンスが親で変更された場合にも何が起こるのでしょうか?シンプルなケースで説明したままにするだけで何が問題になりますか? childAで何かが発生した場合、コールバックを使用して親に通知します。次に、parentBはchildBがそれを知る必要があるかどうかを判断し、そうであればchildBに新しいpropsを渡してその情報を渡します。 –

+0

しかし、 'ChildB'の中にある' ChildB_1'もその情報を必要としますか?その情報をさらに伝播しますか?この場合、 'testList'は共有リソースのようです。しかし、私は 'this.state.panelOpen = 'true/false''、' this.state.currentMode = 0/1/2'などのような他の状態を持っていると思います。どういうわけか、これらの情報をさまざまなレベルの子供のコンポーネントに渡す必要があります。そのため、私は面倒なコールバックで狂ってしまいます。 – Carven

+0

私は何かが恋しくない限り、簡単です。 parentからchildBへ情報を渡すときには、 'Parent.render'メソッドでそれを行い、childBの小道具が「ダーティ」なので、新しい小道具でchildBのレンダリングを呼び出します。 'childB.render'メソッドが呼び出されると、この新しい情報を持つ新しい小道具で' childB_1.render'メソッドを呼び出します。これは、共有リソースを使って簡単に行うことができる方法のように思えるかもしれませんが、他のコンポーネントの状態について心配する必要がないので、事実を単純化します。 –

答えて

6

すべてのプログラマはある時点でこの壁に当たる反応します。私もしました。答えは状態管理のためにReduxを使用することです。あなたは、Reactのネイティブ状態を使用することがいかに面倒であるか経験しました。

Reduxは、Reactと組み合わせて使用​​できる状態管理メカニズムです。したがって、あなたはReactの状態を使用せず、代わりにReduxを使用します。

Reduxは、アプリケーション全体の状態が格納される単一のストアを提供します。 connect()メソッドを使用してコンポーネント内の状態にアクセスできます。

しかし、警告があります。反応コンポーネントのすべてがReduxストアに接続されているわけではありません。アイデアはReduxのストアからの接続の状態を渡すことである連結成分に依存

:接続ダムコンポーネント

  • Reduxのストアへ:components-

    • スマート/連結成分の2つのタイプがあります。 Reactのpropsを介してコンポーネント。接続されたコンポーネントは、ストアから直接ステートを消費することができます。ダムコンポーネントは、レデックスストアに直接接続されていません。接続されたコンポーネントは、propsを介して状態をダムコンポーネントに渡します。それで、あなたが見ると、Reactの状態はまったくバイパスされています。今度は、状態を変更したい場合、次のイベントが発生する必要があります。

      1. イベントはスマート/ダムコンポーネントから発生します。
      2. Actions
      3. actionsに応じて、新しい状態を作成 store
      4. Reducersに派遣されています。
      5. 新しい状態がstoreに格納されます。
      6. Storeprops

      アクションとレデューサーは何を介して接続された構成要素から新しい状態を受け取りますprops

    • ダムコンポーネントを介しconnect()介して接続されたコンポーネントに新しい状態を返しますか?

      アクションは、状態を変更する方法を記述するjavascriptオブジェクト以外は何もありません。

      リダクターは、店舗に発送されたアクションに従って新しい状態ツリーを構築して返す「純粋な」機能です。

      Reduxの - http://redux.js.org/

      Reduxの-サンク - https://github.com/gaearon/redux-thunk

      Reduxの - 佐賀 - https://github.com/yelouafi/redux-saga

  • +0

    あなたの答えをありがとう!私は実際にreduxを認識していますが、私はこれを解決するバニラメソッドを望んでいましたので、追加のライブラリを使用する必要はありません。私は、特に、依存関係の一つとして還元することがあるかもしれない、そうでないかもしれない他の人が再利用できるコンポーネントを作成しようとするなら、これがより良いと思った。 – Carven

    +0

    あなたの簡潔な説明に名誉。 – keshavDulal

    +0

    @Mihir:ちょっと、どのように子供のコンポーネント間の通信.. ?? –

    関連する問題