Yet another store using redux. (Inspired by vuex and dva)
- yax-router: Router plugin for yax (Using react-router).
- HackerNews: HackerNews clone built with Yax, based on dva-hackernews.
$ npm install --save yax
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
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
import yax from 'yax';
import { persistStore, autoRehydrate } from 'redux-persist';
const store = yax(options, autoRehydrate());
persistStore(store, { storage: Storage });
Usage with react-navigation
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);
import yax, {
// Redux original functions
combineReducers,
bindActionCreators,
applyMiddleware,
compose,
// Yax helper functions
composeReducers,
mapReducers,
mapState,
mapActions
} from 'yax';
-
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 namespacetype select = (Selector) => Selector(state, rootState) type Selector = (state, rootState) => any
select()
withoutSelector
will returnstate
-
options.modules
{ [type: string]: Module }
type Module = { state, reducers, actions, modules }
-
enhancer
type StoreEnhancer = (next: StoreCreator) => StoreCreator
const f = (state, action) => {};
const g = (state, action) => {};
// (state, action) => g(f(state, action), action)
const reducer = composeReducers(f, g);
Like with
combineReducers
but composability. More
const foo = (state, action) => {};
const bar = (state, action) => {};
const reducer = mapReducers({ foo, bar });
Used for react-redux
connect
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);
yax is available under the terms of the MIT License.