2015-10-29 17 views
53

私は1週間前にReactを学び始めました。そして、必然的に国家の問題と、コンポーネントがどのようにアプリケーションの他の部分と通信することになっているのでしょうか。私は周りを検索し、Reduxは今月の味であるようです。私はすべてのドキュメントを読み、実際にはかなり革命的なアイデアだと思う。ここに私の考えがあります:Reduxはグローバル状態を賞賛していませんか?

国家は、一般的にかなり悪く、プログラミングのバグの大きな原因であることに合意しています。アプリ全体に散らばっているのではなく、変化するアクションを出さなければならないグローバルな状態ツリーにすべてが集中しているのはなぜですか?興味深いですね。すべてのプログラムが状態を必要とするので、1つの不純な空間にそれを貼り付け、そこから変更するだけでバグを追跡しやすくなります。そして、個々の状態要素をReactコンポーネントに宣言的にバインドし、自動再描画させ、すべてが美しいものにすることもできます。

しかし、このデザイン全体について2つの質問があります。 1つでは、なぜ状態ツリーは不変である必要がありますか?タイムトラベルのデバッグやホットリロードを気にせず、アプリでアンドゥ/リドゥを実装しているとします。これに代えて

case COMPLETE_TODO: 
    return [ 
     ...state.slice(0, action.index), 
     Object.assign({}, state[action.index], { 
     completed: true 
     }), 
     ...state.slice(action.index + 1) 
    ]; 

:ちょうどこれを行うには持っているので、面倒なようだ

case COMPLETE_TODO: 
    state[action.index].completed = true; 

ないに言及し、私はちょうど学ぶためにオンラインホワイトボードを作っていますし、すべての状態変化がのような単純なものかもしれませんブラシストロークをコマンドリストに追加します。このアレイ全体を複製する(数百回のブラシストローク)後は、非常に高価で時間がかかることがあります。

私はアクションを経由して変異しているUIから独立したグローバル状態ツリーでOKだけど、それは本当に不変である必要はありませんか?このような簡単な実装で何が問題になったのですか(非常に原案は1分で書いています)?

var store = { items: [] }; 

export function getState() { 
    return store; 
} 

export function addTodo(text) { 
    store.items.push({ "text": text, "completed", false}); 
} 

export function completeTodo(index) { 
    store.items[index].completed = true; 
} 

これは、排出されたアクションによって非常に単純かつ効率的に変更されたグローバル状態ツリーです。

+1

"1つでは、なぜ状態ツリーは不変である必要がありますか?" ---データが変更されたかどうかを判断するアルゴリズムを提供する必要があります。任意のデータ構造に対して実装することはできません(変更可能な場合)。 'immutablejs'をとり、' return state.setIn([action。index、 'completed']、true); '定型文を減らすため。 – zerkms

+0

PS: 'return state.map(i => i.index == action.index?{... i、completed:true}:i);' – zerkms

答えて

32

Reduxはグローバルな状態を賞賛していませんか?

もちろんです。しかしこれまでに使用したデータベースでも同じことが言えます。 Reduxをメモリ内のデータベースとして扱う方が良いでしょう。これは、コンポーネントが積極的に依存することができます。

不変性により、サブツリーが非常に効率的に変更されたかどうかをチェックすることができます。これは、アイデンティティチェックを簡素化するためです。

はい、あなたの実装が効率的であるが、全体の仮想DOMツリーが何らかの形で操作されるたびに再レンダリングする必要があります。

を使用している場合、それは最終的には実際のDOMに対して差分を実行し、最小限のバッチ最適化された操作を実行しないだろう、反応するが、完全なトップダウンの再レンダリングはまだ非効率的です。

不変ツリーの場合、ステートレスコンポーネントは、依存するサブツリーが以前の値と比較してIDが異なるかどうかをチェックするだけで済みます。そうした場合、レンダリングは完全に回避できます。

+2

これは早すぎる最適化ではありませんか?また、不変オブジェクトを常に複製するコストは、DOMを再レンダリングするよりも少ないことをどのように知っていますか(ReactのバーチャルDOMはこのコストを大幅に軽減しません) –

+3

まあ、この種の最適化は長い間参照:http://bitquabit.com/post/the-more-things-change/)不変なデータ構造の管理は、あなたが考えるかもしれないほど高価ではありません。例えば、ノードが変更された場合、親は連鎖する必要があります - 残りのノードは影響を受けません。したがって、すべてのアクションの*全体のデータ構造を複製するわけではありません。新しいデータ構造を構築するために変更されていないサブコンポーネントを再利用します。 – lorefnon

+0

私のブラシストロークはどうですか?配列の最後に1つの項目を追加するだけで何百もの項目からなるこの配列を複製する不変かつ効率的な方法はありますか? –

関連する問題