Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
67 commits
Select commit Hold shift + click to select a range
785cc94
add npm scripts for docs
vinnymac Jun 28, 2017
2869aa1
add cname for js.org
vinnymac Jun 28, 2017
7e9a9cd
add docs folder with some tocs
vinnymac Jun 28, 2017
4ea504f
add gitbook cli as dev dependency
vinnymac Jun 28, 2017
28db569
ignore _book docs dir
vinnymac Jun 28, 2017
4358370
ignore list for gitbook
vinnymac Jun 28, 2017
2eefbae
npmignore for gitbook files
vinnymac Jun 28, 2017
7965e45
add summary
vinnymac Jun 28, 2017
ab22912
add config for gitbook
vinnymac Jun 28, 2017
a10471f
ignore more gitbook files
vinnymac Jun 28, 2017
084790a
add styling tweak to gitbook
vinnymac Jun 28, 2017
94bbf34
add external resources md
vinnymac Jun 28, 2017
4b2d0bd
Updates docs/api/README.md
vinnymac Jun 28, 2017
605f6e5
Updates docs/api/README.md
vinnymac Jun 28, 2017
62fa586
Updates docs/api/README.md
vinnymac Jun 28, 2017
f105653
Updates docs/api/README.md
vinnymac Jun 28, 2017
cfb8720
Updates docs/api/README.md
vinnymac Jun 28, 2017
182ea1a
Updates SUMMARY.md
vinnymac Jun 28, 2017
e95a653
Merge branch docs into docs
vinnymac Jun 28, 2017
d4cb330
Updates docs/README.md
vinnymac Jun 29, 2017
e098244
Merge d4cb3307adf762f691f00ad4041b8ec633c5b151 into docs
vinnymac Jun 28, 2017
2491d7d
Updates docs/introduction/BeginnerTutorial.md
vinnymac Jun 29, 2017
c8ac56d
Updates README.md
vinnymac Jun 29, 2017
7e4a3ea
Updates docs/introduction/12-motivation.md
vinnymac Jun 29, 2017
04c0cea
Updates docs/introduction/README.md
vinnymac Jun 29, 2017
d1f053e
Updates docs/ExternalResources.md
vinnymac Jun 29, 2017
dddcbc9
Updates docs/api/README.md
vinnymac Jun 29, 2017
5f2ce1e
Updates docs/api/README.md
vinnymac Jun 29, 2017
62120d7
Updates docs/api/README.md
vinnymac Jun 29, 2017
e62446f
Updates docs/api/README.md
vinnymac Jun 29, 2017
9736104
Updates docs/api/README.md
vinnymac Jun 29, 2017
728ec99
fix motivation name
vinnymac Jun 29, 2017
e260520
fix anchor
vinnymac Jun 29, 2017
0ce2ce7
cleanup and add more docs for createActions
vinnymac Jun 29, 2017
8629594
example consistency
vinnymac Jun 29, 2017
7f75356
iron out handleAction
vinnymac Jun 29, 2017
a6a06e9
cleanup main readme with toc and one example
vinnymac Jun 29, 2017
7b5a7c0
add toc for main readme
vinnymac Jun 29, 2017
b358bc6
add terminal indicator
vinnymac Jun 29, 2017
acbf53a
tweak beginner tutorial like readme
vinnymac Jun 29, 2017
886cac7
improve style with some plugins
vinnymac Jun 29, 2017
655b78a
iron out combineActions
vinnymac Jun 29, 2017
95430f4
iron out handleActions
vinnymac Jun 29, 2017
0612029
move relevent bits for createAction(type) up
vinnymac Jun 29, 2017
16afafa
add metacreator example
vinnymac Jun 29, 2017
d391915
add a beginner tutorial
vinnymac Jun 30, 2017
fd7ac87
specify which action
vinnymac Jun 30, 2017
d9804df
tweak conclusion in beginner tutorial
vinnymac Jun 30, 2017
a34b846
update base docs readme
vinnymac Jun 30, 2017
098511a
fix book json repo links
vinnymac Jun 30, 2017
bd97907
rename beginner tutorial
vinnymac Jul 1, 2017
7b90756
Merge branch 'master' into docs
vinnymac Jul 1, 2017
db47601
add undefined identity function back to api ref
vinnymac Jul 1, 2017
ff973e2
rename tutorial title, missed a few
vinnymac Jul 1, 2017
a8c6c1c
add list of contributors
vinnymac Jul 2, 2017
0a91991
break down API reference into pages
vinnymac Jul 2, 2017
5c92387
make contributors a list
vinnymac Jul 2, 2017
ebc39a2
aesthetics for docs link
vinnymac Jul 2, 2017
610dc17
change method page headers
vinnymac Jul 2, 2017
b1bc4f0
Merge branch 'master' into docs
vinnymac Jul 3, 2017
6251467
restore changes to createAction docs
vinnymac Jul 3, 2017
1148ceb
restore changes to handleActions docs
vinnymac Jul 3, 2017
6d12354
use github handles
yangmillstheory Jul 3, 2017
2d4a57b
use markdown links
yangmillstheory Jul 3, 2017
c42a5c5
link to canonical host
yangmillstheory Jul 3, 2017
f3bfe59
remove unnecessary css file
vinnymac Jul 3, 2017
ad85743
remove default theme config
vinnymac Jul 3, 2017
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .bookignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
src/
build/
package.json
webpack*
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,6 @@ es
lib
dist
.idea

# docs generated files
_book
5 changes: 5 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# doc folders
docs
_book
.bookignore
book.json
1 change: 1 addition & 0 deletions CNAME
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
redux-actions.js.org
297 changes: 26 additions & 271 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,258 +6,38 @@

[Flux Standard Action](https://github.com/acdlite/flux-standard-action) utilities for Redux.

## Installation

```bash
npm install --save redux-actions
```

The [npm](https://www.npmjs.com) package provides a [CommonJS](http://webpack.github.io/docs/commonjs.html) build for use in Node.js, and with bundlers like [Webpack](http://webpack.github.io/) and [Browserify](http://browserify.org/). It also includes an [ES modules](http://jsmodules.io/) build that works well with [Rollup](http://rollupjs.org/) and [Webpack2](https://webpack.js.org)'s tree-shaking.

If you don’t use [npm](https://www.npmjs.com), you may grab the latest [UMD](https://unpkg.com/redux-actions@latest/dist) build from [unpkg](https://unpkg.com) (either a [development](https://unpkg.com/redux-actions@latest/dist/redux-actions.js) or a [production](https://unpkg.com/redux-actions@latest/dist/redux-actions.min.js) build). The UMD build exports a global called `window.ReduxActions` if you add it to your page via a `<script>` tag. We *don’t* recommend UMD builds for any serious application, as most of the libraries complementary to Redux are only available on [npm](https://www.npmjs.com/search?q=redux).

## Usage

### `createAction(type, payloadCreator = Identity, ?metaCreator)`

```js
import { createAction } from 'redux-actions';
```

Wraps an action creator so that its return value is the payload of a Flux Standard Action.

`payloadCreator` must be a function, `undefined`, or `null`. If `payloadCreator` is `undefined` or `null`, the identity function is used.

Example:

```js
let noop = createAction('NOOP', amount => amount);
// same as
noop = createAction('NOOP');

expect(noop(42)).to.deep.equal({
type: 'NOOP',
payload: 42
});
```

If the payload is an instance of an [Error
object](https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Error),
redux-actions will automatically set ```action.error``` to true.

Example:

```js
const noop = createAction('NOOP');

const error = new TypeError('not a number');
expect(noop(error)).to.deep.equal({
type: 'NOOP',
payload: error,
error: true
});
```

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

Example:

```js
const noop = createAction('INCREMENT');

// As parameter in handleAction:
handleAction(noop, {
next(state, action) {...},
throw(state, action) {...}
});

// As object key in handleActions:
const reducer = handleActions({
[noop]: (state, action) => ({
counter: state.counter + action.payload
})
}, { counter: 0 });
```

**NOTE:** The more correct name for this function is probably `createActionCreator()`, but that seems a bit redundant.

Use the identity form to create one-off actions:

```js
createAction('ADD_TODO')('Use Redux');
```

`metaCreator` is an optional function that creates metadata for the payload. It receives the same arguments as the payload creator, but its result becomes the meta field of the resulting action. If `metaCreator` is undefined or not a function, the meta field is omitted.

### `createActions(?actionMap, ?...identityActions)`

```js
import { createActions } from 'redux-actions';
```

Returns an object mapping action types to action creators. The keys of this object are camel-cased from the keys in `actionMap` and the string literals of `identityActions`; the values are the action creators.

`actionMap` is an optional object and a recursive data structure, with action types as keys, and whose values **must** be either

- a function, which is the payload creator for that action
- an array with `payload` and `meta` functions in that order, as in [`createAction`](#createactiontype-payloadcreator--identity-metacreator)
- `meta` is **required** in this case (otherwise use the function form above)
- an `actionMap`

`identityActions` is an optional list of positional string arguments that are action type strings; these action types will use the identity payload creator.


```js
const { actionOne, actionTwo, actionThree } = createActions({
// function form; payload creator defined inline
ACTION_ONE: (key, value) => ({ [key]: value }),

// array form
ACTION_TWO: [
(first) => [first], // payload
(first, second) => ({ second }) // meta
],

// trailing action type string form; payload creator is the identity
}, 'ACTION_THREE');
### Table of Contents
* [Getting Started](#gettingstarted)
* [Installation](#installation)
* [Usage](#usage)
* [Documentation](#documentation)

expect(actionOne('key', 1)).to.deep.equal({
type: 'ACTION_ONE',
payload: { key: 1 }
});

expect(actionTwo('first', 'second')).to.deep.equal({
type: 'ACTION_TWO',
payload: ['first'],
meta: { second: 'second' }
});

expect(actionThree(3)).to.deep.equal({
type: 'ACTION_THREE',
payload: 3,
});
```

If `actionMap` has a recursive structure, its leaves are used as payload and meta creators, and the action type for each leaf is the combined path to that leaf:

```js
const actionCreators = createActions({
APP: {
COUNTER: {
INCREMENT: [
amount => ({ amount }),
amount => ({ key: 'value', amount })
],
DECREMENT: amount => ({ amount: -amount }),
SET: undefined // given undefined, the identity function will be used
},
NOTIFY: [
(username, message) => ({ message: `${username}: ${message}` }),
(username, message) => ({ username, message })
]
}
});

expect(actionCreators.app.counter.increment(1)).to.deep.equal({
type: 'APP/COUNTER/INCREMENT',
payload: { amount: 1 },
meta: { key: 'value', amount: 1 }
});
expect(actionCreators.app.counter.decrement(1)).to.deep.equal({
type: 'APP/COUNTER/DECREMENT',
payload: { amount: -1 }
});
expect(actionCreators.app.counter.set(100)).to.deep.equal({
type: 'APP/COUNTER/SET',
payload: 100
});
expect(actionCreators.app.notify('yangmillstheory', 'Hello World')).to.deep.equal({
type: 'APP/NOTIFY',
payload: { message: 'yangmillstheory: Hello World' },
meta: { username: 'yangmillstheory', message: 'Hello World' }
});
```
When using this form, you can pass an object with key `namespace` as the last positional argument (the default is `/`).

### `handleAction(type, reducer | reducerMap = Identity, defaultState)`

```js
import { handleAction } from 'redux-actions';
```

Wraps a reducer so that it only handles Flux Standard Actions of a certain type.
# Getting Started {#gettingstarted}

If a `reducer` function 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 above.

Otherwise, you can specify separate reducers for `next()` and `throw()` using the `reducerMap` form. This API is inspired by the ES6 generator interface.
## Installation

```js
handleAction('FETCH_DATA', {
next(state, action) {...},
throw(state, action) {...}
}, defaultState);
```bash
$ npm install --save redux-actions
```

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

If the reducer argument (`reducer | reducerMap`) is `undefined`, then the identity function is used.

The third parameter `defaultState` is required, and is used when `undefined` is passed to the reducer.
or

### `handleActions(reducerMap, defaultState, )`

```js
import { handleActions } from 'redux-actions';
```

Creates multiple reducers using `handleAction()` and combines them into a single reducer that handles multiple actions. Accepts a map where the keys are passed as the first parameter to `handleAction()` (the action type), and the values are passed as the second parameter (either a reducer or reducer map). The map must not be empty.

If `reducerMap` has a recursive structure, its leaves are used as reducers, and the action type for each leaf is the path to that leaf. If a node's only children are `next()` and `throw()`, the node will be treated as a reducer. If the leaf is `undefined` or `null`, the identity function is used as the reducer. Otherwise, the leaf should be the reducer function. When using this form, you can pass an object with key `namespace` as the last positional argument (the default is `/`).

The second parameter `defaultState` is required, and is used when `undefined` is passed to the reducer.

(Internally, `handleActions()` works by applying multiple reducers in sequence using [reduce-reducers](https://github.com/acdlite/reduce-reducers).)

Example:

```js
const reducer = handleActions({
INCREMENT: (state, action) => ({
counter: state.counter + action.payload
}),

DECREMENT: (state, action) => ({
counter: state.counter - action.payload
})
}, { counter: 0 });
$ yarn add redux-actions
```

### `combineActions(...types)`
The [npm](https://www.npmjs.com) package provides a [CommonJS](http://webpack.github.io/docs/commonjs.html) build for use in Node.js, and with bundlers like [Webpack](http://webpack.github.io/) and [Browserify](http://browserify.org/). It also includes an [ES modules](http://jsmodules.io/) build that works well with [Rollup](http://rollupjs.org/) and [Webpack2](https://webpack.js.org)'s tree-shaking.

Combine any number of action types or action creators. `types` is a list of positional arguments which can be action type strings, symbols, or action creators.
The [UMD](https://unpkg.com/redux-actions@latest/dist) build exports a global called `window.ReduxActions` if you add it to your page via a `<script>` tag. We *don’t* recommend UMD builds for any serious application, as most of the libraries complementary to Redux are only available on [npm](https://www.npmjs.com/search?q=redux).

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

```js
const { increment, decrement } = createActions({
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: 11 })
expect(reducer(undefined, decrement(1)).to.deep.equal({ counter: 9 })
expect(reducer(undefined, increment(new Error)).to.deep.equal({ counter: 0 })
expect(reducer(undefined, decrement(new Error)).to.deep.equal({ counter: 0 })
```
import { createActions, handleActions, combineActions } from 'redux-actions'

Here's an example using `handleActions`:
const defaultState = { counter: 10 };

```js
const { increment, decrement } = createActions({
INCREMENT: amount => ({ amount }),
DECREMENT: amount => ({ amount: -amount })
Expand All @@ -267,43 +47,18 @@ const reducer = handleActions({
[combineActions(increment, decrement)](state, { payload: { amount } }) {
return { ...state, counter: state.counter + amount };
}
}, { counter: 10 });

expect(reducer({ counter: 5 }, increment(5))).to.deep.equal({ counter: 10 });
expect(reducer({ counter: 5 }, decrement(5))).to.deep.equal({ counter: 0 });
expect(reducer({ counter: 5 }, { type: 'NOT_TYPE', payload: 1000 })).to.equal({ counter: 5 });
expect(reducer(undefined, increment(5))).to.deep.equal({ counter: 15 });
```

## Usage with middleware

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

The identity form of `createAction` is a great way to create a single action creator that handles multiple payload types. For example, using [redux-promise](https://github.com/acdlite/redux-promise) and [redux-rx](https://github.com/acdlite/redux-rx):

```js
const addTodo = createAction('ADD_TODO');

// A single reducer...
handleAction('ADD_TODO', (state = { todos: [] }, action) => ({
...state,
todos: [...state.todos, action.payload]
}));
}, defaultState);

// ...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();
export default reducer;
```

## See also
For more complex scenarios we recommend reading our [documentation](https://redux-actions.js.org/).

Use redux-actions in combination with FSA-compliant libraries.
# Documentation

- [redux-promise](https://github.com/acdlite/redux-promise) - Promise middleware
- [redux-rx](https://github.com/acdlite/redux-rx) - Includes observable middleware.
* [Introduction](/docs/introduction)
* [API](/docs/api)
* [Middleware](/docs/middleware)
* [External Resources](/docs/ExternalResources.md)
* [Change Log](/docs/ChangeLog.md)
* [Contributors](/docs/Contributors.md)
14 changes: 14 additions & 0 deletions SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Summary

* [Read Me](/README.md)
* [1. Introduction](/docs/introduction/README.md)
* [1.1 Motivation](docs/introduction/Motivation.md)
* [1.2 Tutorial](/docs/introduction/Tutorial.md)
* [2. API Reference](/docs/api/README.md)
* [2.1 createAction(s)](/docs/api/createAction.md)
* [2.2 handleAction(s)](/docs/api/handleAction.md)
* [2.3 combineActions](/docs/api/combineActions.md)
* [3. Middleware](/docs/middleware/README.md)
* [4. External Resources](/docs/ExternalResources.md)
* [5. Change Log](/docs/ChangeLog.md)
* [6. Contributors](/docs/Contributors.md)
22 changes: 22 additions & 0 deletions book.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"gitbook": ">= 3.0.0",
"title": "Redux Actions",
"plugins": ["edit-link", "prism", "-highlight", "github", "anchorjs"],
"pluginsConfig": {
"edit-link": {
"base": "https://github.com/acdlite/redux-actions/tree/master",
"label": "Edit This Page"
},
"github": {
"url": "https://github.com/acdlite/redux-actions/"
},
"sharing": {
"facebook": true,
"twitter": true,
"google": false,
"weibo": false,
"instapaper": false,
"vk": false
}
}
}
4 changes: 4 additions & 0 deletions docs/ChangeLog.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Change Log

This project adheres to [Semantic Versioning](http://semver.org/).
Every release, along with the migration instructions, is documented on the Github [Releases](https://github.com/acdlite/redux-actions/releases) page.
Loading