Storeact
Zero-configuration store for React. One API rule them all.
Installation
npm i storeact --save
Get started
ES2015+ and Typescript:
import storeact from "storeact";
Example
Let's make an increment/decrement simple application with React:
First, create your store. This is where your application state will live:
const delay = ms resolve ;const CounterStore = let count = 0; return { return count; } { count++; } { count--; } async { await ; this; } ;;
The store is just pure function, we define some APIs and export count value via state() method
Now create your component. With Storeact your component can focus 100% on the UI and just call the actions that will automatically update the state:
const store = ; { const count = store; const increase decrease increaseAsync = store; return <div ="App"> <h1>count</h1> <div> <button =>Increase</button> <button =>Decrease</button> <button =>Increase Async</button> </div> </div> ;}
Storeact 's cool features
- Simple setup
- Simple API (only one)
- Store definition is pure function
- Less boilerplate
- Readability
- Configurable
- Easy to test
- Asynchronous action
- Future actions awaiting
- High performance
- Compatible with Immutable JS
Advanced Usages
Using action context
When an action is dispatching, storeact creates a task for each action call then pass that task as second argument of action. Using action task to control execution flow more easily.
Delay execution using task.delay(ms)
const Store = let count = 0; return { count++; } async { await task; this; } ;;
Using task.cancelOn(...cancelActions)
const Store = return {} async { task; await task; if task return; // update state logic here } ;;
Using task.debounce(ms)
You can use debounce to wait certain amount of time before next execution block
const Store = return {} async { await task; // update state logic here } ;;
Wait for future action dispatching
const Store = return async { const data = await ; this; } {} async { this; // wait until dataFetched action dispatched const data = await task; // do something } ;;
You can improve above example with cancellable searching logic
const Store = return async { const data = await ; this; } {} {} async { // search progress will be cancelled if cancel action dispatched task; await task; this; // wait until dataFetched action dispatched const data = await task; // do something } ;;
Handling async data loading
You can use AsyncValue to handle async data loading easily
const TodoStore = async // create async value object with empty array as default value const list = ; return { // start data loading task; } { // return todos state is promise return todos: listpromise ; } ;;
In React component, to retrieve promised value we use selector util
const store = ;const TodoCount = const count = store; return <h1></h1>;; const App = return <React.Suspense ="Loading..."> <TodoCount /> </React.Suspense> ;;
A "Loading..." message will show if todos promise still not fulfilled
util.loadable()
Using util.loadable() to retrieve Loadable object to render loading progress manually
const store = ;const TodoCount = const loadable = store; if loadablestate === "loading" return <div>Loading...</div>; if loadablestate === "hasError" return <div>Oops something went wrong loadableerrormessage</div>; // loadable.state === 'hasValue' return <h1></h1>;;