0.1.0 • Published 7 years ago

action-creators v0.1.0

Weekly downloads
7
License
MIT
Repository
github
Last release
7 years ago

action-creators

Build Status codecov

Action creators utilities for Redux.
Features:

  • Parameter validation using joi.
  • Debug created actions using debug.
  • No need to define constants.
  • No duplicated namespaces.
  • No duplicated action names.

Notes:

Installation

npm i --save action-creators joi joi-browser

Add to webpack.config.js

resolve: {
  alias: {
    joi: 'joi-browser'
  }
}

Enable debugging

Add to your your app.

if (process.env.NODE_ENV !== 'production') {
  process.env.DEBUG = 'ac:*';
}

Or in webpack.config.js

plugins: [
  new webpack.DefinePlugin({
    'process.env': {
      DEBUG: JSON.stringify(process.env.NODE_ENV !== 'production' ? 'ac:*' : ''),
    },
  }),
],

Quick demo

// user-actions.js

import createNamespace from 'action-creators';

const {createAction} = createNamespace('USERS');

const usersLoaded = createAction('USERS_LOADED',
  ['keyword', 'items', 'pageNumber', 'pageSize'],
  {
    keyword: Joi.string().required(),
    items: Joi.array().required(),
    pageNumber: Joi.number().required(),
    pageSize: Joi.number().required(),
  }
);
expect(usersLoaded('john', [{id: 1, name: 'john'}], 1, 10)).toEqual({
  type: 'USERS/USERS_LOADED',
  payload: {
    keyword: 'john',
    items: [{id: 1, name: 'john'}],
    pageNumber: 1,
    pageSize: 10,
  },
});

Console output:

ac:USERS USERS_LOADED { keyword: 'john', items: [ { id: 1, name: 'john' } ], pageNumber: 1, pageSize: 10 } +0ms

Error reporting

usersLoaded('john', -2, 1, 10)

throws an error

ValidationError: Validation failed for: "USERS/USERS_LOADED" {
  "keyword": "john",
  "pageNumber": 1,
  "pageSize": 10,
  "items" [1]: -2
}

[1] "items" must be an array

Usage with reducers

// user-reducer.js
import {usersLoaded} from './user-actions';

function reducer(state = {}, action) {
  switch (action.type) {
    case usersLoaded.toString(): 
      return {
        ...state,
        ...action.payload,
      }
    default:
      return state;
  }
}

You can also use handleActions from redux-actions.

Motivation

  • During development, action creators can be called with invalid or missing arguments, and it usually causes errors in the reducer function.
  • When using createAction from redux-actions, it's not obvious if the action creator requires any arguments.
    For example:
    increment = createAction('INCREMENT');
    You don't know if you should call increment() or increment(something). In such situation, you always must check the expected payload in the reducer.
  • I needed a fast way to debug created actions. There are existing libraries for logging like redux-logger, but it can sometimes be not convenience. You must expand 3 levels of an object to see the action payload. It's much more readable if the action payload is logged in a single line.

API

  • createNamespace(namespace)
    • Parameters:
      • namespace: String The namespace prefix for all action types. All namespaces must be unique otherwise an error will be thrown.
    • Returns:
      {createAction: Function} Return an object with a createAction property.
  • createAction(type, argNames, schema, transform)
    • Parameters:
      • type: String The action type. All namespaces must be unique otherwise an error will be thrown.
      • argNames: Array An array with arguments.
      • schema: Object A Joi schema. Must be an object containing all props from the argNames array.
      • transform: Function(Object) An optional function to transform the created action. You can use it to change payload or metadata.
    • Returns:
      • Function The action creator

MIT License

Copyright (c) 2017 Łukasz Sentkiewicz