Redux Persist Tree
Simple persisting for redux, redux-persist-tree provides a reliable way to rehydrate your state. The state can be rehydrated on a per value basis, and rehydrated through redux actions or automatically when initialized. Control what data you want to save, and keep your application in a reliable state.
Install
Install with npm:
npm install redux-persist-tree --save
Usage
Import with:
;
Saving Data
There are a couple of things you need to get started. Firstly add the persistMiddleware
to your redux middleware. The middleware takes two arguements. The first is a function which is passed two arguments, a key and the modifies state. The second just gets passed the key. At the bottom of this readme is a list with packages which provide save and load functions for multiple libraries which are compatible with redux-persist-tree.
const saveState = ...const loadState = ... const middleware = ; const store = ;
The next step is to define the structure of your state tree, and use arrays to define what values you want the middleware to persist. The persistTree
funtion takes two parameters: an object to declare the values you want to save, and the store.
const persistor = orders: "data" "updatedAt" "index" auth: values: "id" "name" "email" "birthday" "gender" automatic: true key: "com.app.auth" "data.device": values: "id" "token" automatic: true key: "com.app.device" ; ;
- To access nested reducers define the object key / path in a string. e.g. "data.device"
- You can explicitly declare the key for the async storage using
key
. This is useful for keeping data in sync if your reducer shape changes in time.
Your reducer data will now be saved to storage!
Loading Data
As mentioned above, redux-persist-tree provides a lot of control over how you load and save your data. Data can be loaded using redux actions, to load your data fire a redux action with the prefix LOAD_
. The convention to follow for your actions to work is to prefix LOAD_
with the reducer name in start case. e.g. if you had a reducer named subscriptionOrders
your load action type would be LOAD_SUBSCRIPTION_ORDERS
.
You can then receive this action in your subscriptionOrders
reducer. This action is transformed with the middleware and will contain your saved state in the payload. The code below will apply the saved state to your current state:
case LOAD_SUBSCRIPTION_ORDERS: return ...state ...actionpayload
This allows you to have loading on a per reducer basis separated across the application for stored data instead of having the full application wait for the data to be loaded. These actions can also be fired automatically by setting the automatic
key to true in the first parameter of the persistTree
.
Motivation
Why not just use redux-persist?
For most of my projects it did not provide the fine grained control over rehydration that is usually needed. I often found my apps starting in corrupted states. It did not easily provide rehydration on a per reducer basis, which I could control. Redux-persist-tree does not manipulate your state, it leaves everything to you via the LOAD_
actions which can be received in your reducers.
Providers
Links for save and load functions for diffrent libraries and platforms.
Use Cases
In a production application the reducer which handles authentication was split into two reducers auth
and subscription
. To avoid all the users being authenticated without a subscription when the application was updated... it was possible to rehydrate the subscription data into it's new reducer using redux-persist-tree.
// SubscriptionReducer.js case LOAD_AUTH: /* * We use this to catch people upgrading from older versions of the app, * as auth and subscriptions were joint together. */ if return ...state ...actionpayloadsubscription ; return state;
Todo
- [] Rebuild the library using TypeScript.
- [] Only refresh the state when the declared state (structure) changes
- [] Add cryptography to state using tokens to secure values.
- [] Only trigger persisting after a certain action is triggered.
- [] Add the ability to add a time limit on a per value basis.
- [] Make initialisation easier... modify so the persist tree does not needed to be called twice using two function for setup, could we do this by returning the middleware function from the persistTree function...?
Authors
- Luke Brandon Farrell - Author
License
This project is licensed under the MIT License