When is derived data too complex for reducer selectors?

General advice is to keep the state minimal and use memoized selectors (like reselect lib) for derived data. I understand that there are also times when it is appropriate to put them in a store. I have a lot of derived data in my application that is somewhat expensive to generate, but due to the nature of the way it is used it doesn't need to be generated often. At what point is the data too complex to select a selector and needs to be put into storage?


More details:

I have time series data on which I run some calculations to generate the resulting "views" of the data. The records in each view are calculated based on all the records that came before.

To provide a more specific, somewhat contrived example:

I am currently doing all of this in indexedDB with no reduction.

I have one main table that is purely custom:

type Earnings = {
    id: number;
    time: Date;
    amount: number;
    category: 'A' | 'B' | 'C' | 'D';
};

      

And I have a bunch of hooks that generate "view" tables when data changes Earnings

.

type EarningsByDay = {
    id: number;
    date: Date; // only used to date part
    amountTotal: number;
    maxToDate: number;
};

type EarningsByDateAndCategory = {
    id: number;
    date: Date; // only used to date part
    category: 'A' | 'B' | 'C' | 'D';
    amountTotal: number;
    maxToDate: number;
};

      

In the above views, maxToDate

for is EarningsByDay

computed by finding the max amountTotal

of all records EarningsByDay

that are date

less than the date of the current item. Likewise for EarningsByDateAndCategory

.

If the user edits / deletes / inserts a profit in the past, then all derived data that appeared after that should be restored. However, this is rare and most of the time the user will be adding chronological entries Earnings

(this means that all I have to do is search past entries to find the maximum size).

As part of my plan to transition to pruning, I planned to store the records Earnings

in indexedDB and load them all on startup into the repository (about 5000 records per year of data). Then I would use selectors for the resulting "views".

My concern is that this is too heavy to be suitable for selectors. Also, for a way to re-select memoizes, I would end up regenerating all received data when a record is added.

+3


source to share


1 answer


I have used reselection as described in the question and there have been no problems so far. The biggest drawback is that the form of the state is mostly determined by one main selector, not what is in the store, making the debugging tools less useful. However, I believe this is a limitation of the debugger and not a limitation on the use of selectors as stated. It would be nice to have a tree-like view of the selectors when debugging. I'm fine with the trade-off as the code is much simpler, clearer, and easier to test.



Update. It looks like there are several ways to make the debug selector easier: https://github.com/reactjs/reselect/issues/279

0


source







All Articles