1. createAction(type, payloadCreator = Identity, ?metaCreator): actionCreator with specified type and it will accept a payload

The more correct name for this function is probably createActionCreator(), but it’s too redundant.

createAction('ADD_TODO')('Use the Reudx');
`</pre>

<pre>`import { createAction } from 'redux-action'
`</pre>

<pre>`const increment = createAction('INCREMENT');
expect(increment(42)).to.deep.equal({
  type: 'INCREMENT',
  payload: 42
});
`</pre>

Wraps an action creator so that its return value is the payload of a Flux Standard Action. If no payload creator is passed, or if it's not a function, the identity function is used.

**If the payload is an instance of an Error Object, redux-actions will automatically set `action.error` to true.**

<pre>`const increment = createAction('INCREMENT');

const error = new TypeError('not a number');
expect(increment(error)).to.deep.equal({
  type: 'INCREMENT',
  payload: error,
  error: true
})
`</pre>

`createAction` also return its `type` when used as type in `handleAction` or `handleActions`

<pre>`const increment = createAction('INCREMENT')

// as param in handleAction
handleAction(increment, {
  next(state, action) {...},
  throw(state, action) {...}
});

// as object key in handleActions:
const reducer = handleAction({
  [increment]: (state, action) =&gt; ({
    counter: state.counter + action.payload
  })
}, {counter: 0})
`</pre>

**increment 是 createActions() 创建的一个 actionCreator, 接受 payload 作为参数, 返回一个 action 对象, 该对象传递到 store 中, 并由 store 直接 dispatch 给 handleAction 返回的 reducer**
  1. handleAction(type, reducer | reduceMap, ?defaultState)

    `import { handleAction } from 'redux-action'
    `

    Wraps a reducer so that it only handles Flux Standard Actions of a certain type.

    If a single reducer is passed, it is used to handle both normal actions and failed actions(A failed action is analogous to a rejected promise). You can use this form if you know a certain type of action will never fail, like the increment example.

    Otherwise, you can specify separate reducers for next() and throw(). This API is inspired by the ES6 generator interface.

    `handleAction('FETCH_DATA', {
      next(state, action) {...},
      throw(state, action) {...}
    });
    `

    handleAction 返回的是指定 action 类型的 reducer, 该 reducer 接收到的 action 如果 error=null, 则执行 next 方法, 如果接收到的 action.error=true, 则执行 throw 方法

    createAction(type, payload)返回 action 后, 会自动将 action 传递给 handleAction, 并在 handleAction 内部根据 actionType 执行对应代码块, handleAction 会返回 new State, 通过 combineReducers, 返回给 State

    if either next() or throw() are undefined or null, then the identity function is used for that reducer.

  2. combineActions(…actionTypes)

    Combine any number of action types or action creators. actionTypes is a list of positional arguments which can be action type string, symbols, or action creators.

    This allows you to reduce multiple distinct actions with the same reducer.

    `const {increment, decrement} = createAction({
      INCREMENT: amount => ({ amount }),
      DECREMENT: amount => ({ amount: -amount})
    })
    
    const reducer = handleAction(combineActions(increment, decrement), {
      next:(state, {payload: { amount }}) => ({...state, counter: state.counter + amount}),
      throw: state => ({...state, counter: 0}),
    },{counter: 10})
    
    expect(reducer(undefined, increment(1)).to.deep.equal({counter: 1}))
    expect(reducer(undefined, decrement(1)).to.deep.equal({counter: 0}))
    expect(reducer(undefined, increment(new Error)).to.deep.equal({counter: 0}))
    expect(reducer(undefined, decrement(new Error)).to.deep.equal({counter: 0}))
    `
  3. Usage with middleware

    Redux-actions is handy all by itself, however its real power comes when you combine it with middleware

    The identity form createAction is a great way to create a single action creator that handles multiple payload types.

    For example, using redux-promise and redux-rx

    `const addTodo = createAction('ADD_TODO')
    
    // a single reducer
    handleAction('ADD_TODO', (state = {todos: []}, action) => ({
      ...state,
      todos: [...state.todos, action.payload]
    }));
    
    // ...that works with all of these forms:
    // (Don't forget to use `bindActionCreators()` or equivalent.
    // I've left that bit out)
    addTodo('Use Redux')
    addTodo(Promise.resolve('Weep with joy'))
    addTodo(Observable.of(
      'Learn about middleware',
      'Learn about higher-order stores'
    )).subscribe()