How to Memoize (Deep Compare) Redux Objects Using Reselect with createSelectorCreator()?
Asked Answered
N

0

6

The Situation

Using react redux, in mapStateToProps for one of my container components, I pass down an object with 8+ keys for the sake of convenience. (I am aware that passing objects down is an anti-pattern, but the convenience of passing a singular object rather than many individual props is significant in my case.)

The Question

Can you use reselect to memoize an entire object to pass down through mapStateToProps, only passing it down by deep comparing that entire object? If so, what is the proper way to do so?

My Attempt

I have read the reselect docs section, "Customize equalityCheck for defaultMemoize," and have read through a number of posts where an attempt at memoizing arrays using reselect are made. Based on this knowledge, I have attempted to do the following, but to no success:

import _ from 'lodash';
import { createSelector, createSelectorCreator, defaultMemoize } from 'reselect'

const createDeepEqualSelector = createSelectorCreator(
  defaultMemoize,
  _.isEqual,
);

const getLargeObject = createDeepEqualSelector(
  (state) => {
    // Get the individual values from state
    const {
      val1, val2, val3, val4, val5, val6, val7, val8, val9, val10
    } = state;

    // Create a convenient object that contains all of those values to pass down to props
    const constructedObject = {
      val1, val2, val3, val4, val5, val6, val7, val8, val9, val10
    };

    return constructedObject;
  },
  constructedObject => constructedObject,
);

const mapStateToProps = (state, ownProps) => {
  const objProp = getLargeObject(state);

  return {
    objProp,
    // ... other props
  };
}

The (Unfortunate) Alternative

If I do not do things way, I end up with 8+ individual selectors, with a large createSelector call. This seems more redundant than necessary, and makes me wonder if there is a better way to do this. As a demonstration:

const getVal1 = (state) => state.val1;
const getVal2 = (state) => state.val2;
...

const getLargeObject = createSelector(
  [
    getVal1,
    getVal2,
    ...
  ],
  (
    val1,
    val2,
    ...
  ) => {
    const largeObject = {
      val1,
      val2,
      ...
    };

    return largeObject;
  },
);

Thank you for your any help you can give!

Newfashioned answered 17/10, 2019 at 20:52 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.