Skip to content

Commit

Permalink
Merge b7624d0 into f92b0ed
Browse files Browse the repository at this point in the history
  • Loading branch information
richardcrng committed Jun 4, 2019
2 parents f92b0ed + b7624d0 commit 79431b4
Show file tree
Hide file tree
Showing 39 changed files with 301 additions and 193 deletions.
70 changes: 51 additions & 19 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,7 @@ Write once. Reduce anywhere.

## 30 second demo

### 1. Write once.

### Write once.
```bash
npm install --save redux-leaves
```
Expand All @@ -28,40 +27,73 @@ npm install --save redux-leaves
import { createStore } from 'redux'
import reduxLeaves from 'redux-leaves'

// 1. Define initialState
const initialState = {
counter: 1,
foo: ['foo'],
nest: { deep: {} }
list: ['first'],
nested: { arbitrarily: { deep: 0 } }
}

const reducers = {
increment: leafState => leafState + 1,
push: (leafState, { payload }) => [...leafState, payload],
recurse: (leafState, { payload }, wholeState) => ({ ...leafState, [payload]: wholeState[payload] })
// 2. (Optional) Define custom reducers dictionary
const reducersDict = {
double: leafState => leafState * 2,
appendToEach: (leafState, action) => leafState.map(str => str.concat(action.payload)),
countKeys: (leafState, action, wholeState) => Object.keys(wholeState).length
}

const [reducer, actions] = reduxLeaves(initialState, reducers)
// 3. Grab reducer and actions from reduxLeaves, then create the Redux store
const [reducer, actions] = reduxLeaves(initialState, reducersDict)
const store = createStore(reducer)
```

### 2. Reduce anywhere.
### Reduce anywhere.

```js
// *** KEY ***
// Default: an action creator that ships with Redux-Leaves by default
// Custom: an action creator generated by the custom reducersDict

// Default: increment state.counter
store.dispatch(actions.counter.create.increment())
console.log(store.getState()) // { counter: 2, foo: ['foo'], nest: { deep: {} } }
console.log(store.getState().counter) // 2

// Custom: double state.counter
store.dispatch(actions.counter.create.double())
console.log(store.getState().counter) // 4

// Default: push 'second' to state.list
store.dispatch(actions.list.create.push('second'))
console.log(store.getState().list) // ['first', 'second']

// Custom: append ' item' to each element in state.list
store.dispatch(actions.list.create.appendToEach(' item'))
console.log(store.getState().list) // ['first item', 'second item']

// Default: assign true to key 'newKey' at the top-level of state
store.dispatch(actions.create.assign({ newKey: true }))
console.log(store.getState().newKey) // true

store.dispatch(actions.foo.create.push('bar'))
console.log(store.getState()) // { counter: 2, foo: ['foo', 'bar'], nest: { deep: {} } }
// Custom: update state.nested.arbitrarily.deep with state's number of top-level keys
store.dispatch(actions.nested.arbitrarily.deep.create.countKeys())
console.log(store.getState().nested.arbitrarily.deep) // 4

store.dispatch(actions.nest.deep.create.recurse('counter'))
console.log(store.getState())
/*
{
counter: 2,
foo: ['foo', 'bar'],
nest: {
deep: { counter: 2 }
}
counter: 4,
list: ['first item', ' second item'],
nested: { arbitrarily: { deep: 4 } }
}
*/
```

## Testing

To run all tests locally:

```bash
git clone git@github.com:richardcrng/redux-leaves.git
cd redux-leaves && npm run test a
```

All tests are located alongside their relevant documentation in the [docs](/docs) folder.
1 change: 0 additions & 1 deletion docs/create/apply.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import { createStore } from "redux";
import reduxLeaves from '../../src';

Expand Down
2 changes: 1 addition & 1 deletion docs/create/asArray/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Every single leaf on our `actions` object has access to `create.asArray` methods

If the leaf was initialised with array state, then these methods are also accessible directly through the [`create` API](../defaults.md).

If the current `leafState` is *not* an array, then it is first coerced into an array via lodash's [`_.toArray(leafState)`](https://lodash.com/docs/4.17.11#toArray) method, before the state is updated according to the action dispatched.
If the current `leafState` is *not* an array, then it is first coerced into an array, before the state is updated according to the action dispatched.

## Action creators
- [`.concat(array)`](#concatarray)
Expand Down
1 change: 0 additions & 1 deletion docs/create/asArray/concat.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import { createStore } from "redux";
import reduxLeaves from '../../../src';

Expand Down
1 change: 0 additions & 1 deletion docs/create/asArray/drop.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import { createStore } from "redux";
import reduxLeaves from '../../../src';

Expand Down
1 change: 0 additions & 1 deletion docs/create/asArray/filter.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import { createStore } from "redux";
import reduxLeaves from '../../../src';

Expand Down
1 change: 0 additions & 1 deletion docs/create/asArray/push.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import { createStore } from "redux";
import reduxLeaves from '../../../src';

Expand Down
1 change: 0 additions & 1 deletion docs/create/asBoolean/off.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import { createStore } from "redux";
import reduxLeaves from '../../../src';

Expand Down
1 change: 0 additions & 1 deletion docs/create/asBoolean/on.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import { createStore } from "redux";
import reduxLeaves from '../../../src';

Expand Down
1 change: 0 additions & 1 deletion docs/create/asBoolean/toggle.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import { createStore } from "redux";
import reduxLeaves from '../../../src';

Expand Down
2 changes: 1 addition & 1 deletion docs/create/asNumber/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Every single leaf on our `actions` object has access to `create.asNumber` method

If the leaf was initialised with number state, then these methods are also accessible directly through the [`create` API](../defaults.md).

If the current `leafState` is *not* a number, then it is first coerced into an array via lodash's [`_.toNumber(leafState)`](https://lodash.com/docs/4.17.11#toNumber) method, before the state is updated according to the action dispatched.
If the current `leafState` is *not* a number, then it is first coerced into an array, before the state is updated according to the action dispatched.

## Action creators
- [`.increment([n = 1])`](#incrementn--1)
Expand Down
1 change: 0 additions & 1 deletion docs/create/asNumber/increment.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import { createStore } from "redux";
import reduxLeaves from '../../../src';

Expand Down
15 changes: 10 additions & 5 deletions docs/create/asObject/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ sidebar_label: Object

Every single leaf on our `actions` object has access to `create.asObject` methods.

If the leaf was initialised with [plain object](https://lodash.com/docs/4.17.11#isPlainObject) state, then these methods are also accessible directly through the [`create` API](../defaults.md).
If the leaf was initialised with [plain object](#plain-object) state, then these methods are also accessible directly through the [`create` API](../defaults.md).

If the current `leafState` is *not* a plain object, then it is first coerced into a plain object via lodash's [`_.toPlainObject(leafState)`](https://lodash.com/docs/4.17.11#toPlainObject) method, before the state is updated according to the action dispatched.
If the current `leafState` is *not* a plain object, then it is first coerced into a plain object, before the state is updated according to the action dispatched.

#### Plain object
A plain object is created using `{}`, `new Object()` or `Object.create(null)`

## Action creators
- [`.assign(...sources)`](#assignsources)
Expand All @@ -22,7 +25,7 @@ If the current `leafState` is *not* a plain object, then it is first coerced int
## `assign(...sources)`
**`create.asObject.assign`**

**alias: `create.assign`** *(when `initialLeafState` is a [plain object](https://lodash.com/docs/4.17.11#toPlainObject))*
**alias: `create.assign`** *(when `initialLeafState` is a [plain object](#plain-object))*

Returns an object that, *when dispatched to a store created with the original state tree*, updates the copies all properties from `sources` into the leaf's state.

Expand Down Expand Up @@ -62,11 +65,13 @@ Back to:
## `set(path, value)`
**`create.asObject.set`**

**alias: `create.set`** *(when `initialLeafState` is a [plain object](https://lodash.com/docs/4.17.11#toPlainObject))*
**alias: `create.set`** *(when `initialLeafState` is a [plain object](#plain-object))*

Returns an object that, *when dispatched to a store created with the original state tree*, updates the leaf's state at `path` with `value`.

(This uses lodash's [`_.set(object, path, value)`](https://lodash.com/docs/4.17.11#set), where `object` is `leafState`.)
```js
// TODO update this
```

### Parameters
- `path` *(array | string)*: the path of the property to set
Expand Down
1 change: 0 additions & 1 deletion docs/create/asObject/assign.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import { createStore } from "redux";
import reduxLeaves from '../../../src';

Expand Down
1 change: 0 additions & 1 deletion docs/create/asObject/set.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import { createStore } from "redux";
import reduxLeaves from '../../../src';

Expand Down
2 changes: 1 addition & 1 deletion docs/create/asString/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Every single leaf on our `actions` object has access to `create.asString` method

If the leaf was initialised with string state, then these methods are also accessible directly through the [`create` API](../defaults.md).

If the current `leafState` is *not* a string, then it is first coerced into a string via lodash's [`_.toString(leafState)`](https://lodash.com/docs/4.17.11#toString) method, before the state is updated according to the action dispatched.
If the current `leafState` is *not* a string, then it is first coerced into a string, before the state is updated according to the action dispatched.

## Action creators
- [`.concat(...strings)`](#concatstrings)
Expand Down
1 change: 0 additions & 1 deletion docs/create/asString/replace.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import { createStore } from "redux";
import reduxLeaves from '../../../src';

Expand Down
1 change: 0 additions & 1 deletion docs/create/clear.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import { createStore } from "redux";
import reduxLeaves from '../../src';

Expand Down
1 change: 0 additions & 1 deletion docs/create/reset.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import { createStore } from "redux";
import reduxLeaves from '../../src';

Expand Down
1 change: 0 additions & 1 deletion docs/create/update.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import _ from 'lodash';
import { createStore } from "redux";
import reduxLeaves from '../../src';

Expand Down
52 changes: 34 additions & 18 deletions docs/intro/demo.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,15 @@ import reduxLeaves from 'redux-leaves'
// 1. Define initialState
const initialState = {
counter: 1,
foo: ['foo'],
nest: { deep: {} }
list: ['first'],
nested: { arbitrarily: { deep: 0 } }
}

// 2. Define reducers dictionary
// 2. (Optional) Define custom reducers dictionary
const reducersDict = {
increment: leafState => leafState + 1,
push: (leafState, { payload }) => [...leafState, payload],
recurse: (leafState, { payload }, wholeState) => ({ ...leafState, [payload]: wholeState[payload] })
double: leafState => leafState * 2,
appendToEach: (leafState, action) => leafState.map(str => str.concat(action.payload)),
countKeys: (leafState, action, wholeState) => Object.keys(wholeState).length
}

// 3. Grab reducer and actions from reduxLeaves, then create the Redux store
Expand All @@ -37,24 +37,40 @@ const store = createStore(reducer)
## Reduce anywhere.

```js
// Increment state.counter
// *** KEY ***
// Default: an action creator that ships with Redux-Leaves by default
// Custom: an action creator generated by the custom reducersDict

// Default: increment state.counter
store.dispatch(actions.counter.create.increment())
console.log(store.getState()) // { counter: 2, foo: ['foo'], nest: { deep: {} } }
console.log(store.getState().counter) // 2

// Custom: double state.counter
store.dispatch(actions.counter.create.double())
console.log(store.getState().counter) // 4

// Default: push 'second' to state.list
store.dispatch(actions.list.create.push('second'))
console.log(store.getState().list) // ['first', 'second']

// Custom: append ' item' to each element in state.list
store.dispatch(actions.list.create.appendToEach(' item'))
console.log(store.getState().list) // ['first item', 'second item']

// Default: assign true to key 'newKey' at the top-level of state
store.dispatch(actions.create.assign({ newKey: true }))
console.log(store.getState().newKey) // true

// Push 'bar' to state.foo
store.dispatch(actions.foo.create.push('bar'))
console.log(store.getState()) // { counter: 2, foo: ['foo', 'bar'], nest: { deep: {} } }
// Custom: update state.nested.arbitrarily.deep with state's number of top-level keys
store.dispatch(actions.nested.arbitrarily.deep.create.countKeys())
console.log(store.getState().nested.arbitrarily.deep) // 4

// Recurse the 'counter' property at state.nest.deep
store.dispatch(actions.nest.deep.create.recurse('counter'))
console.log(store.getState())
/*
{
counter: 2,
foo: ['foo', 'bar'],
nest: {
deep: { counter: 2 }
}
counter: 4,
list: ['first item', ' second item'],
nested: { arbitrarily: { deep: 4 } }
}
*/
```

0 comments on commit 79431b4

Please sign in to comment.