2016-09-14 18 views
1

編集可能な値(*大きな値> 1000)の大きいjsonを扱っています。私は全く同じページにレンダリングされていますので、私の状態は単に{ data: bigBigJson }です。大きな状態のReact/Reduxパフォーマンス

最初のレンダリングはかなり長いですが、問題ありません。

入力がonChange(およびreduxアクション)をトリガーすると、値が状態で更新され、全体のレンダリングが再び行われるという問題があります。

私は人々がそれをどのように処理するのだろうか?シンプルなソリューションがあります(必ずしもベストプラクティスではありません)。

注:

  • JSON文書が外部のAPIが提供され、私はそれを

  • を変更することはできません私はそれが複数のです(いくつかのサブ状態に状態を分けることができレベルjson)を使用していますが、よりシンプルで高速なソリューションを望んでいます(おそらくベストプラクティスだと思います)。

  • 私はreactとreduxを使用していますが、immutable.jsではなくすべてが不変です明らかに)

-

更新(DSSの答えについて)

•(ケース1)の状態があるとしましょう:すべて、

{ 
    data: { 
    key1: value1, 
    // ... 
    key1000: value1000 
    } 
} 

keyNが更新されるととにかく状態は再レンダリングされるでしょうか?減速機は次のようなものを返します:

{ 
    data: { 
    ...state.data, 
    keyN: newValueN 
} 

これは本当に私の場合ではありません。

•(ケース2)の状態は、より多くの(単純化されたオーバー)のようなものです:

{ 
    data: { 
    dataSet1: { 
     key1: value1, 
     // ... 
     key10: value1000 
    }, 
    // ... 
    dataSet100: { 
     key1: value1, 
     // ... 
     key10: value1000 
    } 
    } 
} 

dataN.keyNが更新されると、私は減速

{ 
    data: { 
    ...state.data, 
    dataN: { 
     ...state.data.dataN, 
     keyN: newValueN 
    } 
    } 
} 

に戻ってくる、私は私がやっていると思いますそれは本当に素晴らしいとは思わないので、何か間違っている。 は、それはそのような何かを変更します

// state 
{ 
    dataSet1: { 
    key1: value1, 
    // ... 
    key10: value1000 
    }, 
    // ... 
    dataSet100: { 
    key1: value1, 
    // ... 
    key10: value1000 
    } 
} 

// reducer 
{ 
    ...state, 
    dataN: { 
    ...state.dataN, 
    keyN: newValueN 
    } 
} 

を最後に、ちょうど私の減速は、(単純化されたまだ少し)どのように見えるかをここでより多くので、私の場合についてより具体的に:

import get from 'lodash/fp/get' 
import set from 'lodash/fp/set' 
// ... 
// reducer: 
// path = 'values[3].values[4].values[0]' 
return { 
    data: set(path, { 
    ...get(path, state.data), 
    value: newValue 
    }, state.data) 
} 

で•場合あなたは不思議に思っている、私はちょうど使用することはできません。他のプロパティとして

data: set(path + '.value', newValue, state.data)

をも更新する必要があります。

+1

「keyNが更新された場合は、すべての状態がそのまま再描画されますか?減速器は、」と答えます。いいえ、keyNのみが再レンダリングされます。 _other_アイテムをレンダリングするコンポーネントは、(React-Reduxはこれを行います)オブジェクト参照が(そのキーのために)同じであることを認識し、レンダリングをスキップします。 – DDS

+0

すべての値が同じ反応コンポーネントで使用/レンダリングされる場合(1つの 'render()'のみ)?唯一の方法は、これをより小さなサブコンポーネントに分割することです。 (それは生成され、動的に '.connect()'されます) – Cohars

+1

あなたはそれをうまくやっているように見えます(少なくとも{ ...状態、 データN:{ ... state.dataN、 keyN: newValueN } } '、lodash fpにあまりよく知られていません。多くのコンポーネントを使用すると、接続された各コンポーネントに通知が送られるため、処理が遅くなることに注意してください。これは速いですが、たとえ速くても多くのことをやっていると結構です。あなたが対処していることの1つは、オブジェクトキーを繰り返し実行する前に毎回フェッチする必要があることです。これには時間がかかります。キーをデータオブジェクトの横の状態(キー付き)に格納する方がよい場合があります。 – DDS

答えて

4

すべてが再レンダリングされる理由は、ストア内のすべてが変更されたためです。それは同じように見えるかもしれません。すべてのプロパティが同じ値を持つ可能性があります。しかし、すべてのオブジェクト参照が変更されています。つまり、2つのオブジェクトが同じプロパティを持っていても、それらは依然として別個のアイデンティティを持っています。

React-Reduxは、オブジェクトが変更されたかどうかを判断するためにオブジェクトIDを使用するため、オブジェクトが変更されていない場合は常に同じオブジェクト参照を使用するようにしてください。 Redux状態は不変でなければならないため、新しい状態で古いオブジェクトを使用することは問題を起こさないことが保証されます。不変オブジェクトは、整数や文字列を再利用できるのと同じ方法で再利用できます。

あなたのジレンマを解決するには、減速機でJSONとストア状態のサブオブジェクトを比較して比較できます。同じ場合は、必ずストアオブジェクトを使用してください。 React-Reduxは、同じオブジェクトを再利用することによって、それらのオブジェクトを表すコンポーネントが再レンダリングされないようにします。つまり、1000個のオブジェクトのうちの1つだけが変更された場合、1つのコンポーネントだけが更新されます。

React keyプロパティも正しく使用してください。それらの1000個のアイテムのそれぞれは、JSONからJSONに変わらない独自のIDが必要です。

最後に、あなた自身の状態をそのような更新の影響を受けやすくすることを検討してください。状態のロードと更新時にJSONを変換することができます。たとえば、IDでキー入力された項目を保存すると、更新プロセスが大幅に高速化されます。

+0

ありがとう、良いアドバイス/洞察力がたくさんあります。 About:_ "オブジェクトが変更されていないときは常に同じオブジェクト参照を使用するようにしてください" _ユーザーが入力内に入力すると、値が同じではないため、オブジェクト/状態は変更されます。私はすべての私の 'キー'が正しく設定されていることを再確認します。私はいくつかの事例で私の質問を編集した、あなたが見ることができる場合は素晴らしいだろう:) – Cohars

関連する問題