redux made ok

  • okdux

Downloads in past


3.12.05 years ago5 years agoMinified + gzip package size for okdux in KB


Okdux 👌
CircleCI NPM Downloads
This lib was created for reducing pain from redux boilerplate.


npm install --save okdux

yarn add okdux


import { createStore } from "redux";
import { connect } from "react-redux";

import { createActions, createState, build } from "okdux";

const actions = createActions({
  inc: build.action<string>()

const counterState = createState(0);
// different types of counters
const state = createState({ counter: countersState });

counterState.on(actions.inc, (state, p) => {
  return state + 1;

//[optional]auto bind all actions to redux
//store is redux store
state.createStore((reducer)=> createStore(reducer, {}));
// or
const store = createStore(state.reducer, {});

countersState.select(store.getState()); // will return state from root
countersState.select(store.getState()); // will return state from root

// select only counter from root state
// this component will be reuseable and you won't care about where your reducer are placed
// also you will get types suggestions
const enhancer = connect(countersState.select(counter=>({ counter })))

// dispatch actions
// all actions are autobinded to store after using .use action
// you can assign one action to multiple stores
// to access plain action call inc.raw();
// actions are autobinded in case of


createState({ //plain obj or different state }) => StateBuilder

create state from plain object or compose from different state
const counter = createState(0);

const state = createState({ counter });

ALERT: YOU CAN PASS to createState either plain obj or map of states
this is ok
const counter = createState(0);
const counter2 = createState(0);

const state = createState({ counter, counter2 });

this is not ok
const counter = createState(0);
const counter2 = createState(0);

const state = createState({ counter, counter2, name: "6" /* not ok*/ });
const state = createState({ counter, counter2, name: createState("name") }); // this is ok


StateBuilder.on(Action:Action, handler:(substate: any, ActionPayload)=>new substate)

Add handler to substate It's like building reducer but with using .on instead of switch cases in handler as second argument you will get action payload and you have to return new state

StateBuilder.select(RootStateObject)=> state

selects state related to your state builder

StateBuilder.select((subState)=>mappedState)=> mappedState

state with map is equivalent to mapFn(StateBuilder.select({}));
it will return substate related to some stateBuilder Example:
// somewhere in state file;
const counterState = createState(0);

//somewhere in component
// now you can select your counter state and don't care about counter placement in store
const enhancer = connect(countersState.select(counter => ({ counter })));

ALERT: you can have only one stateBuilder mounded to root state
const st = createState(2);
const rootSTate = createState({
  st2: st
}); // not ok
const makeSt = () => createState(2);
const rootSTate = createState({
  st: makeSt(),
  st2: makeSt()
}); // ok

StateBuilder.reducer: PlainReducer

reducer property it's encapsulated reducer inside state builder

StateBuilder.use(dispatchFn): void

makes all actions binded using on handler autobinded to this function so you won't have to use mapDispatchToProps

StateBuilder.createState(createStoreFn): store

same as use
const state = createState(0);
state.createStore(reducer => createStore(reducer, {}));
// or simpler

StateBuilder.reset(action): StateBuilder

reset reducer value to default same as state.on(action, ()=>initialValue)

createActions({ string: ActionFactory })

import { build, createState, createApi } from "okdux";
const counter = createState(0);

const actions = createApi(counter, {
  increment(state, payload) {
    return { ...state, payload };
  decrement(state, payload) {
    return { ...state, payload };