2017-08-18 10 views
2

私はそれを正しくすることができません。ここでは、私は2つのウィジェット、TabBarとTabNavigatorを作った。 tabNavには、インデックスcurrentSelectedTabの状態が含まれています。だから、TabBarがユーザのクリックを受け取ると、それは親(TabNav)に何か(コールバック付きで)するように通知します。親は、親愛なるタブバーを選択して、新しいタブを選択します:currentSelectedTab と同時に、 tabNavは、タブの適切なコンテンツを表示します。ReactJsの機能的スタイルがカプセル化を破る

これまでのところ良いです。しかし、今私はアプリケーションがTabNavを特定のタブに設定できるようにしたい。私が小道具としてそれを紹介するとすぐに、tabnavでcurrentSelectedTabのカプセル化が解除されます。アプリケーション内で定義する必要があります。そして、これは吸う。

OOPパースペクティブでは、TabNavウィジェットにsetCurrentTabがありますが、FPでは、特にReactではこれが禁止されています。ウィジェットの唯一のエントリードアは小道具です。 (Refsは悪いですよね?)

これは、TabBarがユーザークリックを受け取ると、TabNavでコールバックを呼び出し、TabNavはアプリケーションで定義された上位コールバックを呼び出す必要があることを意味します。このコールバックによってアプリケーションの状態が変更され、currentSelectedTabが設定されます。そのため、これはPropsを介してTabNavに渡されます。

currentSelectedTabをTabNavの外側で定義する必要があるという事実は単に恐ろしいことです。そうは思わない?それは、コンポーネントのカプセル化を壊すことに私に見えます。どのようにそれを正しく行うには?フラックス?同じこと:currentSelectedTabをグローバルな状態で定義する必要はありません。

基本的には、すべてが機能していると、上部に巨大な状態があり、いくつかのウィジェットに属するものが含まれているようです。カプセル化は深く壊れている。

誰かが私にここで何が間違っているのか説明できますか?

+0

いくつかのコードは、あなたが何をしているのかを視覚化するのに役立ちます –

+0

'TabBar'できれいに処理できなかった' TabNavigator'の機能は何ですか? TabBarでナビゲーションを処理させて、 'defaultSelectedTab'の小道具を渡すことができなかった理由を想像していません。彼らがどちらもTabの名前を持っているという事実は、すでにかなり結びついていることを示唆しているようだ。 TabBarを他のものに再利用しようとしていますか?一般的なユースケースは何ですか? – philraj

+0

これは一般的なやり方です。たとえばflexで。 [that](http://help.adobe.com/en_US/flex/using/WSc2368ca491e3ff92-59bf082612135c9e688-8000.html#WS70ef25857c0d979e-5df5db17123beb1864c-8000)を参照してください。彼らのViewStackは私のTabNavであり、ButtonBarは私のTabBarです –

答えて

0

私はそれに対処する正しい方法を見つけました。 アプリの責任は、単に初期値を提供することです。 initialSelectedTabIndex TabNavigatorは、アプリケーションではなく、現在のインデックスの所有者で、適切なことを行うためにTabBarでコールバックを使用します。selectedTabIndexなどの内部状態を更新します。 このようにしてカプセル化が壊れることはありません。アプリケーションは、新しいインデックスを再送するためにコールバックを使用する必要はありません、それはそれを行うTabNavになります。

componentWillReceivePropsがTabNavで発生すると、何もしません。これは初期化されていないため、内部状態を小道具initialSelectedTabIndexで上書きしたくないためです。

2

選択されたタブを命令型言語に設定するパブリックメソッドを持つことは、同じことを反応させることを意味するpropを持つこととあまり変わりません。

コンポーネント外の一部のプロパティを制御する必要があると感じると、当然、それは公的契約の一部になります。反応においては、共通のOOP言語(パブリッククラスのメソッド/フィールド)で、これが大部分、好ましくは小道具である。

react propが内部状態を直接表現する必要はありませんが、その状態の初期値として小道具を使用することは完全にOKです。小道具が変更されているときにカプセル化された内部状態を変更できるようにする特別なフックcomponentWillReceivePropsがあります。

これは少し物事を明確にすることを望みます。

+0

私はcomponentWillReceivePropsを試しましたが、私は問題はそこに解決策がないと思います。私は "私は小道具で現在のタブインデックスを渡す"と言っていると同時に、 "私は現在のタブインデックスを使用しています"と言うことはできません。私はこの種のバグを抱えていました: 私は小道具を介してウィジェットの開始インデックスとして0を渡し、次にタブをクリックします。私はタブ2に行きます。何らかの理由で再レンダリングがアプリで発生するので、 「componentWillReceiveProps」を介して「0」が入力され、現在の状態「1」が上書きされます。だから私は今のタブを何の理由もなく残しました。 –

+0

componentWillReceivePropsは 'nextProps'パラメータを受け入れます。 nextProps.selectedTabIndexが現在のものと比較して変更されているかどうかを確認できます。この厳密には、パブリックメソッドを呼び出してインデックスを変更する必要があります。それが呼び出される理由がなくても、同じインデックスで毎回呼び出すことはありません。代わりに、変更が発生したことがわかっているときにのみ呼び出します。小道具では、その小道具(公共の「インターフェース」)に必要な変更が加えられたことが分かっているときにのみ、同じ構成要素がその状態を変化させる。 – Amid

+0

これは機能しません。 nextProps.selectedTabIndexは私の場合は廃止予定です。なぜなら私はこれの所有者がどこにあるのか決定しなかったからです。アプリの場合は動作し、ウィジェットは変更する必要があることをアプリに通知します。あなたが状態でこ​​れを管理することを決定するとすぐに、それをカプセル化するために、それは動作しません、アプリは同期していません。このフィールドは2つの場所に保存することはできません。 –

関連する問題