Skip to content
Yet another store using redux. (Inspired by vuex and dva)
JavaScript
Branch: master
Clone or download
Latest commit 476a05e Aug 10, 2019
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
examples/counter change api Apr 15, 2017
src update deps Aug 10, 2019
test add helpers May 25, 2017
.babelrc version 0.4.0: deps updates Nov 7, 2018
.eslintrc init Apr 14, 2017
.gitignore version 0.4.0: deps updates Nov 7, 2018
.travis.yml Update .travis.yml May 22, 2019
README.md change readme Jun 1, 2017
package.json version 0.4.2 Aug 10, 2019

README.md

Yax (Yet Another Store)

NPM version NPM downloads Build Status Coverage Status Dependency Status Greenkeeper badge

Yet another store using redux. (Inspired by vuex and dva)

Demos & Plugins

  • yax-router: Router plugin for yax (Using react-router).
  • HackerNews: HackerNews clone built with Yax, based on dva-hackernews.

Getting Started

Install

$ npm install --save yax

Usage Example

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);

API Reference

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

composeReducers(...reducers)

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

const foo = (state, action) => {};
const bar = (state, action) => {};
const reducer = mapReducers({ foo, bar });

mapState and mapActions

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);

Report a issue

License

yax is available under the terms of the MIT License.

You can’t perform that action at this time.