james emanon
james emanon

Reputation: 11837

Redux and Reselect and saving cached data

So, as I understand it - reselect is good for derived state between different state tree parts, or derived state from different reducers. BUT, what if I have something like:

<ul>
  <li onClick="this.getItems({id: 122})">Item 1
  <li onClick="this.getItems({id: 342})">Item 2
  <li onClick="this.getItems({id: 8767})">Item 3
  <li onClick="this.getItems({id: 12})">Item 4
</ul>

etc.. basically, I am not deriving any composition of state data or anything but I want to "limit" repeat actions/reducer calls by serving up previously 'asked for calls'. So, is Reselect good for this? If so, any general example. The examples I have seen compute derived state. I was thinking as a solution is to decorate my actions with a memoization/cache function that will hand back previously requested data if there, else, move forwward with the action call. ie..

@cachedProductItem
export function getItems({id}) {
  // if id is cached, return it from the decorator wrapped component, else
  // call the action
  return {
    type: .....,
    id
  }
}

Upvotes: 2

Views: 1168

Answers (1)

user1095118
user1095118

Reputation: 4506

Reselect

Reselect is used to avoid re renders base on computations of state

take the following code

const mapStateToProps = ({someStateKeys, someEntity}) => {
  return {
    newProp = someStateKeys.map(key => someEntity[key])
  }
}

even if the state doesn't change map will return a new array so the newProp key will fail the object equality check and force a re-render

The createSelector function provided by reselect memoize's the map returning the same object if the props have not changed so a re render will not occur

Debouncing Actions with Redux Middleware

What it sounds like you want to do is possibly limit the rate in which an action can be fired.

This will only allow an action to be fired every n ms

A simple middleware would could like this

const pending = {};

const debounceMiddleware = () => next => action => {
  const { debounce } = action.meta || {}; 
  if (!debounce) {
    return next(action);
  }
  if (pending[action.type]) { 
    clearTimeout(pending[action.type]);
  }
  pending[action.type] = setTimeout(
    () => {
      delete pending[action.type];
      next(action);
    },
    debounce 
  );
};

Upvotes: 1

Related Questions