Jumpstate
Jumpstate is a simple and powerful state management utility for Redux.
- Lightweight at 2kb
- Write less, read easier, teach faster
- Effects (Async actions and side-effects)
- Global hook system
- No action creators
- No action constants
- No dispatching required
Why do we love it?
- It provides a clear and understandable way of managing state
- It has massively reduced the amount of code we maintain
- It is easy to learn/teach, and reads extremely well
- It has replaced the need for thunks and sagas.
Did you know? Jumpstate is the core state-manager for Jumpsuit, So if you like what you see, you'll likely love Jumpsuit as well!
Installation
$ npm install jumpstate --save
Complete Example
// Import Jumpstate // Create a state with some actionsconst Counter = // Create a sandboxed state with similar actionsconst SandboxCounter = // Create an asynchronous effect // Create a hook // Setup your redux however you likeconst reducers = counter: Counter counter2: Counter2 sandboxCounter: SandboxCounter const store = // Somwhere in a connected component...React // You can still use the dispatcher and getState for traditional redux anytime you wantconsole // displays the current global state // You take it from here...
Global States
Creating a global state is easy, and in return you get a reducer that is usable with redux right out of the box.
// Use `State` to make a new global stateconst counterReducer = // Now you can use the reducer it returned in your redux setupconst store = // And call global actions using jumpstate's `Actions` registryActions
State Actions
When you create a state, you assign action functions that can change that state in some way. When called, each action received the current state
, and the payload
that was passed with the call.
It's important to maintain immutability here, and not mutate the current state in these actions. Doing so will meddle with debugging, time-travel, and the underlying redux instance.
{ return count: statecount + 1 }
In the example above, we created a new state with our updated count. Win!
Effects
Effects, at their core, are asynchronous actions. They build on the concepts of thunks and sagas but are much easier to understand and use. Unlike thunks, Effects have their own redux actions, and their callback are executed because of those actions. You also gain all of the benefits of a side-effects model, without having to deal with the convoluted api of redux-saga.
To create an effect:
const postFetchEffect = // Call the effectActions// or alternatively
Hooks
A simple hook system that lets you monitor your state for actions or conditions and do just about anything you want.
To create a hook:
// You can hook into any actions, even ones from external libraries!const formLoadedHook = // Load google analytics if it is not yet loadedconst analyticsLoadedHook = // Cancel a hook:formLoadedHookanalyticsLoadedHook
Actions
All actions (including effects) are available via the Actions
object.
ActionsActionsmySandboxActions
Sandboxed States
Sandboxed states are namespaced and isolated from global events. Their state can only be modified by calling actions via Actions.prefixName.actionName()
or directly via their reducer methods. They also return a reducer that is redux-compatible out of the box.
// Create a sandboxed state by passing a name as the first parameterconst SandboxedCounter = // Now you can use the reducer it returned in your redux setupconst store = // Sandboxed actions are accessible through the prefix on Actions or as methods on its reducer!ActionsotherCounter// orSandboxedCounter
Action Creators
Jumpstate automatically provides you with access to the action creators that power your actions. Every action has a corresponding action creator method on:
- The importable
ActionCreators
object - The reducer that the action belongs to via
myReducer.actionCreators
- The effect via
myEffect.actionCreator
const globalCounterReducer = const myCounterReducer = const incrementAsyncEffect = // All of the available action creators are available... // On The ActionCreators object:ActionsCreators === type: 'increment' payload: 2ActionsCreatorsmyCounter === type: 'myCounter_increment' payload: 2ActionsCreators === type: 'incrementAsync' payload: 2 // And on the reducer/effect the action belongs to:globalCounterReduceractionCreators === type: 'increment' payload: 2myCounterReduceractionCreators === type: 'myCounter_increment' payload: 2incrementAsyncEffectactionCreator === type: 'myCounter_increment' payload: 2
A common patter in redux is to export your actionCreators and bind/utilize them in your components. Now you can!
// Examples are on the way :)
Removing/Cancelling Effects and Hooks
If you know you are done with an effect or hook and want to free up some memory, you can cancel them:
// Effectsconst myEffect = myEffect // Hooksconst myHook = myHook
Help and Contributions
PRs and issues are welcome and wanted. Before submitting a feature-based PR, please file an issue to gauge its alignment with the goals of the project.
License
MIT © Jumpsuit