Outstated
Simple hooks-based state management for React
Like unstated but with hooks
Installation
npm install outstated
Example
import React useState from 'react';import ReactDOM from 'react-dom';import Provider useStore from 'outstated'; const store = const count setCount = ; const increment = ; const decrement = ; const reset = ; return count increment decrement reset;; { const count increment decrement reset = ; return <div> <button =>-</button> <span>count</span> <button =>+</button> <button =>reset</button> </div> ;} ReactDOM;
For more examples, see the example/
directory.
Guide
Unstated is awesome, but doesn't really use hooks.
Can we build something similar to unstated with hooks to make something even nicer?
Introducing Outstated
I really like unstated. I really like hooks. I wanted a simple hook-based app state management solution. This is why I've built Outstated.
Outstated is built on top of React hooks, context and patterns surrounding those elements.
It has three pieces:
Store
It's a place to store our state and some of the logic for updating it.
Store is a very simple React hook (which means you can re-use it, use other hooks within it, etc).
; const store = { const state setState = ; const update = ; return state update;};
Note that stores use useState
hook from React for managing state.
When you call setState
it triggers components to re-render,
so be careful not to mutate state
directly or your components won't re-render.
useStore
Next we'll need a piece to introduce our state back into the tree so that:
- When state changes, our components re-render.
- We can depend on our store state.
- We can call functions exposed by the store.
For this we have the useStore
hook which allows us to get global store instances
by using specific store constructor.
{ const count decrement increment = ; return <div> <span>count</span> <button =>-</button> <button =>+</button> </div> ;}
<Provider>
The final piece that Outstated has is <Provider>
component.
It has two roles:
- It initializes global instances of given stores (this is required because React expects the number of hooks to be consistent across re-renders)
- It uses a set of contexts to pass initialized instances of given stores to all the components down the tree.
Different context is used for each store. This allows to only trigger re-renders in the components that use the updated store. As a (minor) downside of this approach - nested contexts are created for each store you pass.
;
Testing
Whenever we consider the way that we write the state in our apps we should be
thinking about testing.
We want to make sure that our state containers have a clean way to test them.
Because our containers are just hooks, we can construct them in tests and assert different things about them very easily.
; ;