mobx-store
A data store with declarative querying, observable state, and easy undo/redo. You can disable history too.
Why
Query your data declaratively like it is SQL
// Create storeconst store = // SELECT name, age FROM users WHERE age > 18 ORDER BY age LIMIT 1
Schedule reactions to state changes
{ console} // Create empty storeconst store = // Schedule log so that it happens every time the store mutatesstore // log is invoked on the push because the store mutated/* logs [] because 1 < 10*/ // log is invoked on the push because the store mutated/* logs [12]*/
Easy undo and redo
// value of test is [1, 2, 3]store // value of test is [] againstore // value of test is [1, 2, 3] again
Easy interop with React
One of the best things about the store is that you can use it with mobx-react
because it's based
upon MobX. This also means that when you mutate your objects you don't need setState() calls because
MobX will handle all the updating for you.
const store = const Objects =
Example
Here's a quick demo I put together to demonstrate the observable state and undo/redo features. It uses the code you can find later in the README to make changes to the store automatically persist to localstorage.
Installation
npm install --save mobx-store
Keeping your bundle small
If you're concerned about the extra weight that lodash will add to your bundle you can install babel-plugin-lodash
npm install --save-dev babel-plugin-lodash
and add it to your .babelrc
"presets": // es2015, stage-whatever "plugins": /* other plugins */ "lodash"
this way you can do modular imports, and reduce the size of your bundles on the frontend
Tutorial
The store is structured as an object that holds either an array or object for each key. For example, something like
numbers: ui: {}
To create a store all you need to do is
// Create empty store and initialize laterconst store = store // Create store with initial stateconst store =
and to get access to specific key such as users you would just call.
With arrays you can manipulate them as if they are native arrays, but if you made an object you
interact with it using the get
and set
methods
Reading from and writing to the store
mobx-store has a simple lodash powered API.
-
Reading from the store is as simple as passing lodash methods to the store function. In order to pass methods to the store without actually executing them you can import from
lodash/fp
. -
Writing to the store is done by calling the regular array methods as well the methods MobX exposes such as
replace
on the store object.
const store = // read current value of store -- [] // write [1, 2, 3] to store // push 4 into the store // read [2, 3, 4] from store
You can also chain methods to create more complex queries by passing an array of functions to the store.
const store = // Sort users by id and return an array of those with ids > 20const result =
If you save the result of one of your queries to a variable,
you can continue working with the variable by using the chain
API
// Take the top 3, and return an array of their namesstore // Filter again to get those with ids less than 100, take the top 2, and return an array of their names capitalizedstore
Scheduling reactions to state change
Reacting to state changes is done through the schedule
API. You pass one to many arrays to the function.
The first element of the array is your function, and the following elements are the arguments of your array.
For example mobx-store comes with an adapter for reading and writing to localstorage, which looks like this.
{ const data = localStorage if data return JSON return {}} { return localStorage} read write
Using this we can schedule writing to the localstorage whenever the store mutates.
// Create store initialized with value of localstorage at "info"const store = // schedule a reaction to changes to the state of the storestore
and you're done. Every change you make to this instance of mobx-store will persist to localstorage.
Undo and redo
To use undo and redo pass the name of a key in your store as a parameter. Make sure not to undo if you haven't altered the state of your store, or if you have called it too many times already, and likewise make sure not to call redo if you haven't yet called undo.
const store = store // error store // undo pushstore // redo push store // error
You can avoid errors by using the functions canRedo
and canUndo
if store storeif store store
You can limit the history of the undo by passing limitHistory
to the store config
// Can only undo up to 10 timesconst store =
Limiting history should be usually be unnecessary as mobx-store doesn't store the entire object in history like Redux does, which potentially can take up a lot of memory. Instead, it only stores information about what changed, and only creates the new state when you call undo or redo.
Using with React
Read and apply the instructions you can find at mobx-react to make your components update when your store updates. The gist of it is that you just
and wrap the component that is using your store in it.
Credit
- Thanks to @mweststrate for writing https://github.com/mobxjs/mobx
- The declarative querying is an improvement upon the cool ideas here https://github.com/typicode/lowdb