yax
Version:
Yet another store using redux. (Inspired by vuex and dva)
265 lines (209 loc) • 6.01 kB
Markdown
Yax (Yet Another Store)
=======================
[](https://www.npmjs.com/package/yax)
[](https://www.npmjs.com/package/yax)
[](https://travis-ci.org/d-band/yax)
[](https://coveralls.io/github/d-band/yax?branch=master)
[](https://david-dm.org/d-band/yax)
[](https://greenkeeper.io/)
> Yet another store using redux. (Inspired by vuex and dva)
## Demos & Plugins
- [yax-router](https://github.com/d-band/yax-router): Router plugin for yax (Using react-router).
- [HackerNews](https://github.com/d-band/yax-hackernews): HackerNews clone built with Yax, based on dva-hackernews.
## Getting Started
### Install
```bash
$ npm install --save yax
```
### Usage Example
```javascript
import yax from 'yax';
const delay = ms => new Promise(resolve => setTimeout(resolve, ms));
const count = {
state: 0,
reducers: {
addDone (state, payload) {
return state + payload;
},
minusDone (state, payload) {
return state - payload;
}
},
actions: {
async add ({ commit }, payload) {
await delay(1);
commit('addDone', payload);
},
async minus ({ commit }, payload) {
await delay(1);
commit('minusDone', payload);
}
}
};
const store = yax({
modules: { count }
});
store.subscribe(() =>
console.log(store.getState())
);
store.dispatch({
type: 'count/add',
payload: 2
});
store.dispatch({
type: 'count/minus',
payload: 1
});
```
Usage with React
```javascript
import React from 'react';
import { render } from 'react-dom';
import { Provider } from 'react-redux';
import yax from 'yax';
import count from './count';
import App from './App';
const store = yax({
modules: { count }
});
render(
<Provider store={store}>
<App />
</Provider>,
document.getElementById('root')
);
```
Usage with `redux-persist`
```javascript
import yax from 'yax';
import { persistStore, autoRehydrate } from 'redux-persist';
const store = yax(options, autoRehydrate());
persistStore(store, { storage: Storage });
```
Usage with `react-navigation`
```javascript
import yax, { compose, composeReducers, mapReducers } from 'yax';
import { StackNavigator } from 'react-navigation';
const AppNavigator = StackNavigator(AppRouteConfigs);
const initialAction = AppNavigator.router.getActionForPathAndParams('Login');
const initialState = AppNavigator.router.getStateForAction(initialAction);
const navReducer = (state = initialState, action) => {
const nextState = AppNavigator.router.getStateForAction(action, state);
return nextState || state;
};
const navEnhancer = createStore => (reducer, preloadedState, enhancer) => {
const appReducer = composeReducers(
reducer,
mapReducers({
nav: navReducer
})
);
return createStore(appReducer, preloadedState, enhancer);
};
const store = yax({
modules: { foo, bar }
}, compose(
navEnhancer,
otherEnhancers
));
// In modules with `commit`
import { NavigationActions } from 'react-navigation';
const LOGIN = NavigationActions.navigate({ routeName: 'Login' });
const BACK = NavigationActions.back();
...
commit(LOGIN, true);
commit(BACK, true);
```
## API Reference
```javascript
import yax, {
// Redux original functions
combineReducers,
bindActionCreators,
applyMiddleware,
compose,
// Yax helper functions
composeReducers,
mapReducers,
mapState,
mapActions
} from 'yax';
```
### `yax(options = {}, [enhancer])`
- **`options.state`**
The root state object for the store.
- **`options.reducers`**
```
{ [type: string]: Reducer }
```
```
type Reducer = (state, payload) => state
```
> `state` will be module local state if defined in a module
- **`options.actions`**
```
{ [type: string]: Action }
```
```
type Action = ({ dispatch, commit, select }, payload) => Promise
```
```
type dispatch = (type, payload, isRoot) => Promise
type commit = (type, payload, isRoot) => any
```
> `isRoot=true` will dispatch actions or commit reducers in the global namespace
```
type select = (Selector) => Selector(state, rootState)
type Selector = (state, rootState) => any
```
> `select()` without `Selector` will return `state`
- **`options.modules`**
```
{ [type: string]: Module }
```
```
type Module = { state, reducers, actions, modules }
```
- **`enhancer`**
```
type StoreEnhancer = (next: StoreCreator) => StoreCreator
```
> [redux store enhancer](http://redux.js.org/docs/Glossary.html#store-enhancer)
### `composeReducers(...reducers)`
```javascript
const f = (state, action) => {};
const g = (state, action) => {};
// (state, action) => g(f(state, action), action)
const reducer = composeReducers(f, g);
```
### `mapReducers(reducers)`
> Like with `combineReducers` but composability. [More](https://github.com/reactjs/redux/pull/2059#issuecomment-256798218)
```javascript
const foo = (state, action) => {};
const bar = (state, action) => {};
const reducer = mapReducers({ foo, bar });
```
### `mapState` and `mapActions`
> Used for [react-redux `connect`](https://github.com/reactjs/react-redux/blob/master/docs/api.md#connectmapstatetoprops-mapdispatchtoprops-mergeprops-options)
```
const App = ({ foo, bar, addFoo, addBar }) => {
addFoo(payload);
addBar(payload);
return <span>{foo} / {bar}</span>;
};
connect(
mapState({
foo: 'foo/value',
bar: 'bar/value'
}),
mapActions({
addFoo: 'foo/add',
addBar: 'bar/add'
})
)(App);
```
## Report a issue
* [All issues](https://github.com/d-band/yax/issues)
* [New issue](https://github.com/d-band/yax/issues/new)
## License
yax is available under the terms of the MIT License.