-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #117 from richardcrng/documentation-redo
Documentation redo
- Loading branch information
Showing
79 changed files
with
2,140 additions
and
3,003 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
--- | ||
id: actions | ||
title: actions | ||
hide_title: true | ||
sidebar_label: actions | ||
--- | ||
|
||
# `actions` | ||
|
||
## Arbitrary property paths | ||
|
||
The `actions` object returned by `reduxLeaves` can take an arbitrary path of properties after it, which typically correspond to a 'leaf' at the corresponding path from your state. | ||
|
||
```js | ||
import reduxLeaves from 'redux-leaves' | ||
|
||
const initialState = { | ||
counter: 0, | ||
arbitrary: { | ||
nested: { | ||
path: ['hi!'] | ||
} | ||
} | ||
} | ||
|
||
const [reducer, actions] = reduxLeaves(initialState) | ||
|
||
// state.counter | ||
console.log(typeof actions.counter) // 'object' | ||
|
||
// state.arbitrary.nested | ||
console.log(typeof actions.arbitrary.nested) // 'object' | ||
|
||
// state.arbitrary.nested.path | ||
console.log(typeof actions.arbitrary.nested.path) // 'object' | ||
|
||
// but also works for paths not in your initial state | ||
console.log(typeof actions.not.in.my.initial.state) // 'object' | ||
``` | ||
|
||
## Accessing `create` | ||
|
||
For a given arbitrary property path, you have two options: navigating to a deeper property / leaf, or accessing the [`create`](create.md) property. | ||
|
||
```js | ||
// Access create at the state root | ||
console.log(typeof actions.create) // 'function' | ||
|
||
// Go deeper | ||
console.log(typeof actions.arbitrary) // 'object' | ||
|
||
// Access create at state.arbitrary | ||
console.log(typeof actions.arbitrary.create) // 'function' | ||
|
||
// Go deeper | ||
console.log(typeof actions.arbitrary.nested.path) | ||
|
||
// Access create at state.arbitary.nested.path | ||
console.log(typeof actions.arbitrary.nested.path.create) // 'function' | ||
``` | ||
|
||
Once you've accessed `create`, you can't go arbitrarily deeper beyond that. | ||
```js | ||
console.log(typeof actions.create.arbitrary) // 'undefined' | ||
``` | ||
|
||
This is because the `create` key accesses the Redux-Leaves [action creator (`create`) API](create.md) at the corresponding leaf of state. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
import reduxLeaves from '../../src'; | ||
|
||
describe('actions can take an arbitrary path of properties after it', () => { | ||
const initialState = { | ||
counter: 0, | ||
arbitrary: { | ||
nested: { | ||
path: ['hi!'] | ||
} | ||
} | ||
} | ||
|
||
const [reducer, actions] = reduxLeaves(initialState) | ||
|
||
test('Any arbitrary path returns an object', () => { | ||
expect(typeof actions.counter).toBe('object') | ||
expect(typeof actions.arbitrary.nested).toBe('object') | ||
expect(typeof actions.arbitrary.nested.path).toBe('object') | ||
expect(typeof actions.not.in.my.initial.state).toBe('object') | ||
}) | ||
|
||
test('Any arbitrary path has the create function property', () => { | ||
expect(typeof actions.create).toBe('function') | ||
expect(typeof actions.counter.create).toBe('function') | ||
expect(typeof actions.arbitrary.nested.create).toBe('function') | ||
expect(typeof actions.arbitrary.nested.path.create).toBe('function') | ||
expect(typeof actions.not.in.my.initial.state.create).toBe('function') | ||
}) | ||
|
||
test("You can't access arbitrary paths from create", () => { | ||
expect(typeof actions.create.arbitrary).toBe('undefined') | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
--- | ||
id: create | ||
title: create | ||
hide_title: true | ||
sidebar_label: create | ||
--- | ||
|
||
# `create` | ||
|
||
When you access the `create` property from any arbitrary path from the [`actions`](actions.md) object, you access the Redux-Leaves action creators API. | ||
|
||
Consider the `actions` object returned below. | ||
```js | ||
import { createStore } from 'redux' | ||
import reduxLeaves from 'redux-leaves' | ||
|
||
const initialState = { | ||
counter: 0, | ||
arbitrary: { | ||
nested: { | ||
path: ['hi!'] | ||
} | ||
} | ||
} | ||
|
||
const reducersDict = { | ||
convertToFoobar: () => 'foobar' | ||
} | ||
|
||
const [reducer, actions] = reduxLeaves(initialState, reducersDict) | ||
``` | ||
|
||
* `actions.counter.create` corresponds to creating actions at `state.counter`; | ||
* `actions.arbitrary.nested.path.create` corresponds to creating actions at `state.arbitrary.nested.path`; | ||
* `actions.create` corresponds to creating actions at the `state`'s root. | ||
|
||
## `create[creatorKey]` | ||
### Action creators | ||
You can access action creators (functions) from the `create` API at any leaf by using their [`creatorKey`](creatorKeys.md) as a property, both for the default ones and any custom ones you've defined. | ||
|
||
```js | ||
// Example defaults: update, set, push | ||
console.log(typeof actions.counter.create.update) // 'function' | ||
console.log(typeof actions.arbitrary.nested.create.set) // 'function' | ||
console.log(typeof actions.arbitrary.nested.path.create.push) // 'function' | ||
|
||
// Custom creatorKey of 'convertToFoobar' | ||
console.log(typeof actions.create.convertToFoobar) // 'function' | ||
console.log(typeof actions.arbitrary.nested.path.create.convertToFoobar) // 'function' | ||
``` | ||
|
||
### Actions | ||
Executing these functions then create the actions that you should dispatch to your Redux store. | ||
|
||
```js | ||
const store = createStore(reducer) // using reducer from reduxLeaves | ||
console.log(store.getState().counter) // 0 | ||
|
||
const updateCounter = actions.counter.create.update | ||
|
||
store.dispatch(updateCounter(5)) | ||
console.log(store.getState().counter) // 5 | ||
|
||
store.dispatch(updateCounter(3)) | ||
console.log(store.getState().counter) // 3 | ||
``` | ||
|
||
### Optional `actionType` argument | ||
Rather than directly accessing action creators from `create`, you can optionally provide an `actionType` string as an argument to `create` before accessing the action creator functions: | ||
|
||
```js | ||
// Defaults, e.g. update creatorKey | ||
console.log(typeof actions.counter.create.update) // 'function' | ||
console.log(typeof actions.counter.create('UPDATE_COUNTER').update) // 'function' | ||
|
||
// Custom creatorKey of 'convertToFoobar' | ||
console.log(typeof actions.create.convertToFoobar) // 'function' | ||
console.log(typeof actions.create('CONVERT_TO_FOOBAR').convertToFoobar) // 'function' | ||
``` | ||
|
||
Providing an `actionType` string in this way does not change the way that the reducer will respond to actions; it merely overrides the created action's `type` property to be the string passed in (which might be desirable for a debugging perspective for Redux DevTools, for example): | ||
|
||
```js | ||
const createDefaultIncrement = actions.counter.create.increment | ||
const createNamedIncrement = actions.counter.create('NAMED_INCREMENT').increment | ||
|
||
console.log(store.getState().counter) // 3 | ||
|
||
const defaultIncrement = createDefaultIncrement() | ||
console.log(defaultIncrement.type) // 'counter/INCREMENT' | ||
dispatch(defaultIncrement) | ||
console.log(store.getState().counter) // 4 | ||
|
||
const namedIncrement = createNamedIncrement() | ||
console.log(namedIncrement.type) // 'NAMED_INCREMENT' | ||
dispatch(namedIncrement) | ||
console.log(store.getState().counter) // 5 | ||
``` | ||
|
||
(It is safe to override name in this way because the Redux-Leaves `reducer` does not switch over the action's `type`.) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { createStore } from 'redux' | ||
import reduxLeaves from '../../src'; | ||
|
||
describe('create has action creators keyed by default and custom creatorKeys', () => { | ||
const initialState = { | ||
counter: 0, | ||
arbitrary: { | ||
nested: { | ||
path: ['hi!'] | ||
} | ||
} | ||
} | ||
|
||
const reducersDict = { | ||
convertToFoobar: () => 'foobar' | ||
} | ||
|
||
const [reducer, actions] = reduxLeaves(initialState, reducersDict) | ||
|
||
test('All creates have default creatorKeys like update, set and push', () => { | ||
expect(typeof actions.counter.create.update).toBe('function') | ||
expect(typeof actions.arbitrary.nested.create.set).toBe('function') | ||
expect(typeof actions.arbitrary.nested.path.create.push).toBe('function') | ||
}) | ||
|
||
test('All creates also have supplied custom creatorKeys', () => { | ||
expect(typeof actions.create.convertToFoobar).toBe('function') | ||
expect(typeof actions.arbitrary.nested.path.create.convertToFoobar).toBe('function') | ||
}) | ||
|
||
const store = createStore(reducer) | ||
|
||
test("Executing an action creator returns an action to dispatch to the Redux store", () => { | ||
const updateCounter = actions.counter.create.update | ||
|
||
store.dispatch(updateCounter(5)) | ||
expect(store.getState().counter).toBe(5) | ||
|
||
store.dispatch(updateCounter(3)) | ||
expect(store.getState().counter).toBe(3) | ||
}) | ||
|
||
describe('create can take a string argument as actionType', () => { | ||
test('If given this argument, it still has properties corresponding to default and custom provided creators', () => { | ||
expect(typeof actions.counter.create('UPDATE_COUNTER').update).toBe('function') | ||
expect(typeof actions.create('CONVERT_TO_FOOBAR').convertToFoobar).toBe('function') | ||
}) | ||
|
||
test('The created actions have the supplied actionType as type', () => { | ||
const createNamedIncrement = actions.counter.create('NAMED_INCREMENT').increment | ||
const namedIncrement = createNamedIncrement() | ||
|
||
expect(namedIncrement.type).toBe('NAMED_INCREMENT') | ||
const currVal = store.getState().counter | ||
store.dispatch(namedIncrement) | ||
expect(store.getState().counter).toBe(currVal + 1) | ||
}) | ||
}) | ||
}) |
Oops, something went wrong.