2

再選択ドキュメントの例に従います。

import { createSelector } from 'reselect'

const shopItemsSelector = state => state.shop.items

const subtotalSelector = createSelector(
  shopItemsSelector,
  items => items.reduce((acc, item) => acc + item.value, 0)
)

典型的な redux アプリでは、結果に影響はありませんがsubtotalSelector、ユーザーが を更新すると が再計算されます。item.nameこれを回避する方法はありますか?

4

2 に答える 2

1

2 つのソリューション:

  1. なるがままに。大量のアイテムがない限り、ブラウザーの計算能力は再計算を処理するのに十分です。

  2. item オブジェクトから価格を分離します。つまり、state.shop.items.itemNames(id-name ペアstate.shop.items.itemValuesを含む) と (id-value ペアを含む) があります。次に、 のみがitemValuesセレクターに渡されます。

于 2016-12-23T02:31:58.823 に答える
0

私は同様の問題を抱えており、それを回避するための一種のハックを見つけました。

フィルターのセットが複雑で、フィルター処理するアイテムが膨大な数にあります。フィルター状態の一部には、表示状態が含まれます。表示状態の変化を無視したいので、常に巨大なリストをフィルタリングしません。これは簡単な解決策です:

const getFilters = createSelector(
    state => state.filters,
    filters => {
        const filtersWithoutDisplay = {};
        const ignoreObj = { collapsed: null };
        for (let filterGroup in filters) {
            filtersWithoutDisplay[filterGroup] = Object.assign({}, filters[filterGroup], ignoreObj);
        }
        // We create a new object every time, so this cannot be memoized properly unless we stringify.
        return JSON.stringify(filtersWithoutDisplay);
    }
);

解析する必要がある JSON 文字列を返しますが、これはプリミティブであるため、別のセレクターへの入力として、実際の内容が変更されない場合は再計算をトリガーしません。それは一種のハックです。

createSelectorCreatorここで説明されているように、セレクター関数の外部でオブジェクトを定義し、常に同じ参照を保持し、この同じパターンに従って内部を変更し、プルしてカスタムの深い等値チェックを使用することもできますhttps://github.com/ reactjs/reselect#q-why-is-my-selector-recomputing-when-the-input-state-stays-the-same . これはおそらくより良い方法ですが、それが言うように:

代替の equalityCheck 関数または状態更新関数の詳細な等価性チェックのコストが、毎回再計算するコストよりも大きくないことを常に確認してください。

これは、JSON.stringify ハックにも当てはまります。私は巨大なリストに対してはしませんが、フィルターに対しては確かにそうします。

私の状況では、フィルター値はフィルター表示設定とは別の問題である可能性があり、これを分離したいのはこれだけではない可能性があるため、状態をリファクタリングすることをお勧めします。

于 2017-05-25T00:35:36.677 に答える