A slightly opiniated redux framework with the goal to reduce boilerplate and to modularize application logic.
Anatomy of a bit
Required exports
// ./bits/myTestBit.js // A unique name for the bit.const name = 'myTestBit'; // The initial state of the bit.const state = foo: true bar: 'someText'; // Simplified action creators.// Just return the payload for redux action.const actions = !foo bar: bar ; // Simplified reducers.// Just mutate the draft state, the original will be left untouched.// Instead of providing the full action only the payload is provided.// Each action must have one matching reducer with the same name.const reducers = { draftfoo = payload; } { draftbar = bar; };
Optional exports
Selectors
// ./bits/myTestBit.js// ... // Selectors// For memoized or more complex selectors you might want to use reselect.const selectors = statefoo ? statebar : statebar;
Action types
If the action types are required elsewhere in your application you may export them using an included helper function:
// ./bits/myTestBit.js;// ... const types = ;
React state container
Export state container as default:
// ./bits/myTestBit.js;// ... name actions selector /*optional*/;
Usage
Use createStore
from redux-bits
to create your redux store instead of using the original
one from redux
.
You may add any third party reducers, middlewares and/or store enhancers.
// store.js;; // all options are optionalconst config = bits: myTestBit reducers: {} middlewares: enhancers: initialState: {}; config;
Usage with React
To use bits with react, export the state container from the bit (see above). The default state container accepts a function as a child that receives the bit's state as parameter:
// ./testComponent.js <div> <MyTestBit> <p>Foo: foo</p> <p>Bar: bar</p> <a onClick=fooAction>Foo action</a> </MyTestBit></div>;
Alternative state container
The default state container follows the function as a child pattern.
In addition, redux-bits
provides an alternative render prop Component
pattern,
for those who don't like functions as a child.
Using this approach makes testing the component much easier.
// ./bits/myTestBit.js;// ... name actions selector /*optional*/;
// ./testComponent.js const TestRenderer = <p>Foo: foo</p> <p>Bar: bar</p> <a onClick=fooAction>Foo action</a>; <div> <MyTestBit Component=TestRenderer /></div>;
Use selectors to optimize render performance of your components
Bit selectors
Selectors that are defined in the corresponding bit may be used by setting the selector
prop to
the selector's name.
// ./fooComponent.js; <div> <MyTestBit selector='fooBar'> <p>Foo: fooBar</p> <a onClick=fooAction>action creators are still available</a> </MyTestBit></div>;
Custom selectors
You may use any selector function as selector
prop.
In addition to the globalState the bit's state is provided as second parameter.
// ./barComponent.js; <div> <MyTestBit selector= globalValue: globalStatesomeGlobalValue bar: bitStatebar > <p>Bar: bar</p> <p>Global value: globalValue</p> </MyTestBit></div>;