function createDataReducer(actionKey = 'data') {
  /**
   * Creates reducer for data state. Used to create data and ordered reducers.
   * Changed by `SET` or `SET_ORDERED` (if actionKey === 'ordered'), `MERGE`,
   * `NO_VALUE`, and `LOGOUT` actions.
   * @param {object} [state={}] - Current data redux state
   * @param {object} action - Object containing the action that was dispatched
   * @param {string} action.type - Type of action that was dispatched
   * @param {string} action.path - Path of action that was dispatched
   * @returns {object} Data state after reduction
   * @private
   */
  return function dataReducer(state = {}, action) {
    switch (action.type) {
      case SET:
        return setWith(
          Object,
          getDotStrPath(action.path),
          action[actionKey],
          state
        )
      case MERGE:
        const previousData = get(state, getDotStrPath(action.path), {}) // eslint-disable-line no-case-declarations
        const mergedData = assign(previousData, action[actionKey]) // eslint-disable-line no-case-declarations
        return setWith(Object, getDotStrPath(action.path), mergedData, state)
      case NO_VALUE:
        return setWith(Object, getDotStrPath(action.path), null, state)
      case REMOVE:
        if (actionKey === 'data') {
          return recursiveUnset(getDotStrPath(action.path), state)
        }
        return state
      case LOGOUT:
        // support keeping data when logging out - #125
        if (action.preserve) {
          if (Array.isArray(action.preserve)) {
            return pick(state, action.preserve) // pick returns a new object
          } else if (isObject(action.preserve)) {
            return action.preserve[actionKey]
              ? preserveValuesFromState(state, action.preserve[actionKey], {})
              : {}
          }
          throw new Error(
            'Invalid preserve parameter. It must be an Object or an Array'
          )
        }
        return {}
      default:
        return state
    }
  }
}
Creates reducer for data state. Used to create data and ordered reducers.
Changed by `SET` or `SET_ORDERED` (if actionKey === 'ordered'), `MERGE`,
`NO_VALUE`, and `LOGOUT` actions.
@param {string} actionKey - Key of state for which to make reducer (data or ordered)
@returns {Function} Data reducer
@private