lore-hook-reducers

Creates a set of reducers for each model from blueprints

Purpose

This hook creates the set of default reducers for every model.

To learn more about the behavior of this hook, see the Reducers documentation.

Config

To learn more about the configuration options for this hook, see the documentation for config/reducers.js.

Purpose

Sometimes child reducers need to execute in a specific order, which is the case with the default Lore reducers. There are some edge cases when caching optimistic data, and others that occur during routing and page loading, that require the find reducer to use the information just calculated by the byId and byCid reducers. So the execution cycle with the parent post reducer looks something like this:

// virtual reducer: src/reducers/post.js
module.exports = function(state, action) {
  var _byId = byId(state.byId, action);
  var _byCid = byCid(state.byId, action);
  var _find = find(state.byId, action, {
    nextState: {
      byId: _byId,
      byCid: _byCid
    }
  });

  return {
    byId: _byId,
    byCid: _byCid,
    find: _find,
  }
}

In order to properly keep track of the query and pagination information and prevent duplicates related to optimistic updates and page load order, the find reducer uses the information from the other two. So basically, it has a dependency on the first two reducers, which are passed in as a third options argument.

If you find yourself creating reducers that need information from other reducers (and you don't want to take full control of the parent reducer) you can specify those dependencies in the config/reducers.js file. The explicit representation of the scenario above looks like this:

// config/reducers.js

module.exports = {
  dependencies: {
    post: {
      find: ['byId', 'byCid']
    }
  }
}

That object structure says "the post.find reducer needs byId and byCid to execute first and needs the result of those two reducers passed to it in the third options argument".

So if you need to create a custom reducer and place it alongside the blueprints, but also need information from the blueprints, you can simple declare it and lore will make sure everything is called in the right order.

Example Config File

module.exports = {
  dependencies: {
    post: {
      byId: [],
      byCid: [],
      find: ['byId', 'byCid']
    }
  }
};

Configuration Options

dependencies

The dependency map between a top-level parent reducer like post and it's child reducers that determines execution order and whether (if any) data about the next state should be passed between them.