希望可以帮助大家使用和了解redux-persist的相关能力
npm i --save redux-persist
如果你使用了
immutable
npm i --save redux-persist-immutable
-
// store.js
-
-
import { persistStore, autoRehydrate }
from
'redux-persist'
-
//
or
-
//
import { persistStore, autoRehydrate }
from
'redux-persist-immutable'
-
-
-
const store = createStore(
-
...
-
autoRehydrate()
-
)
-
-
persistStore(store, {storage: AsyncStorage})
-
redux-persist react native 端本地存储指定使用AsyncStorage
。Android是以K-V的形式存储在本地sqlite中。
iOS 是直接存沙盒文件了
RCTAsyncLocalStorage_V1
目录中的manifest.json
中
-
const config = {
-
storage: AsyncStorage,
-
blacklist:[
'weather'],
-
whitelist:[
'display ']
-
}
-
persistStore(store, config)
redux-persist 支持配置和黑名单。仅仅持久化白名单中的数据或者不持久化黑名单中的数据。
由于大部分情况下我们的state都会非常的大。强烈建议建议大家使用白名单对持久化数据做过滤。
支持在数据保存和还原之前做状态的转换。
lz-string
对数据做压缩需要考虑挂载顺序对数据影响
-
persistStore(
store, {
-
transforms: [expireTransform,immutableTransform,encryptTransform]
-
});
当然还可以根据自己的需求进行自定义,并不复杂
我们知道persist做了缓存数据的加载,这里就涉及到三个状态,初始化的state、缓存state、reducer后的state。那么这三者是如何合并的?这是一个问题。autoRehydrate
就是用来解决这个问题的。
其参数stateReconciler
中定义了合并规则。
如果没有定义这使用默认的defaultStateReconciler
每次版本升级都或多少伴随着state的变化,那么新state和持久化的state之间应该如何保持一致性?
之前可能会有一些简单粗暴的处理,比如删除缓存。
而中间件migrate就是解决这个问题的优雅方案。他可以指定对应state的版本。通过定义manifest
来描述每个版本的变化情况。从而实现新老state的结构一致。
如:
-
import { compose, createStore }
from
'redux'
-
import { persistStore, autoRehydrate }
from
'redux-persist'
-
import createMigration
from
'redux-persist-migrate'
-
-
const manifest = {
-
1:
(state) => ({...state,
staleReducer:
undefined})
-
2:
(state) => ({...state,
app: {...state.app,
staleKey:
undefined}})
-
}
-
-
let reducerKey =
'app'
-
const migration = createMigration(manifest, reducerKey)
-
const enhancer = compose(migration, autoRehydrate())
-
-
const store = createStore(reducer,
null, enhancer)
-
persistStore(store)
migrate
找出reduce的版本号,并遍历执行manifest中大于此版本号的方法。最终返回一个最新版本号写入reduce.version
中!
persist
的写缓存时机 store
监听器触发的时候,也就是状态发生变化的时候。但是如果我们频繁操作 store 就会出现大量的 native 读写。影响性能,于是 persist 提供了 debounce 机制。store 监听器触发的时候并不立刻执行,而是使用setInterval
做了一下延时。 保证指定时间内只执行一次。
上面我们知道数据的存储是以key: 'reduxPersist:' + reducer key
的类型存储的。默认 keyPrefix
是 reduxPersist
。 这个是可以使用 config.keyPrefix
进行修改定制的。更具不同的业务定义不同的 key 进行业务区分。也很好的避免了数据覆盖的问题
persist 本质上是基于同一份Native存储的,所以本身就是共享的。如要访问其他SDK的state则需要加上添加上对应的key
可能会冲突,所以建议在reducer name中加上前缀?
需要定制修改persist,将不同的SDK state 存入不同的数据库!
persistStore 执行的时候。
Store 监听器触发的时候,也就是状态发生变化时。