redux-symbiote
Write your actions and reducers without pain
Usage
const initialState = error: null accounts: loading: false const symbiotes = accounts: loading: ...state loading: true ...state loading: false error ...state loading: false accounts const actions reducer =
Also you can use CommonJS:
const createSymbiote = // ...
Demo
API
Create symbiote
Create action handlers + reducer
Example:
const initialState = value: 1 data: 'another' const symbiotes = ...state value: statevalue + 1 ...state value: statevalue - 1 ...state value ...state data ...state data: data + statedata const actions reducer = // { type: 'increment' } // { type: 'setValue', payload: [4] } // { type: 'decrement' } // { type: 'setData', payload: ['bar'] } // { type: 'concatData', payload: ['foo '] } // State here { value: 3, data: 'foo bar' }
When you call actions.setValue
symbiote calls your action handler with previousState and all arguments spreaded after state.
Nested example
const initialState = value: 1 data: 'another' const symbiotes = value: ...state value: statevalue + 1 ...state value: statevalue - 1 data: ...state data ...state data: data + statedata const actions reducer = // { type: 'value/increment' } // { type: 'value/decrement' } // { type: 'data/set', payload: ['bar'] } // { type: 'data/concat', payload: ['foo '] }
Options
Third parameter in createSymbiote
is optional string
or object
.
If string
passed, symbiote converts it to { namespace: 'string' }
.
Object has optional properties:
namespace
isstring
— set prefix for each action typedefaultReducer
is(previousState, action) -> newState
— called instead of return previous stateseparator
isstring
— change separator of nested action types (default/
)
ActionHandler##toString
You can use action as action type in classic reducer or in handleAction(s)
in redux-actions
const initialState = /* ... */ const symbiotes = foo: bar: ...state data: arg1 atad: arg2 const actions = const reducer =
How to use reducer
createSymbiote
returns object with actions
and reducer
.
Created reducer already handles created actions. You don't need to handle actions from symbiote.
// accounts.jsconst actions reducer = // reducer.js// another imports const reducer =
Why?
Redux recommends creating constants, action creators and reducers separately.
const ACCOUNTS_LOADING_START = 'ACCOUNTS_LOADING_START'const ACCOUNTS_LOADING_FAILED = 'ACCOUNTS_LOADING_FAILED'const ACCOUNTS_LOADING_FINISH = 'ACCOUNTS_LOADING_FINISH' { return type: ACCOUNTS_LOADING_START } { return type: ACCOUNTS_LOADING_FAILED payload: error } { return type: ACCOUNTS_LOADING_FINISH payload: accounts } const initialState = error: null accounts: loading: false { return state}
So much boilerplate.
Let's look at redux-actions.
const actions = accounts const initialState = error: null accounts: loading: false const accountsReducer =
But we have some duplicate in action creators properties and reducer.
Let's rewrite it to redux-symbiote:
const initialState = error: null accounts: loading: false const symbiotes = ...state loading: true ...state loading: false accounts ...state loading: false error const actions reducer: accountsReducer =
That's all. accounts/loading
is an optional namespace for actions types.
To reduce noise around loading actions try symbiote-fetching
.
Contributors
Thanks goes to these wonderful people (emoji key):
Sergey Sova 📖 💻 💡 🤔 ⚠️ |
Arutyunyan Artyom 👀 🤔 🐛 💻 |
Igor Kamyshev 📦 ⚠️ |
Ilya 🐛 |
Ivanov Vadim 📖 |
Аnton Krivokhizhin 📦 🚇 |
Viacheslav 🤔 👀 |
Dmitri Razin 🐛 🎨 |
Surgie Finesse 💻 |
This project follows the all-contributors specification. Contributions of any kind welcome!