native数据类型 react_React-Native 数据持久化探索

使用RN也有一段时间了,但是却未试过在RN项目中实现数据的持久化,虽然项目继承了react-redux,但是数据存在于内存中,用户关闭APP后,需要重新初始化数据,网上大多RN数据持久化都是将一些数据存在AsyncStorage中,但是却打断了与redux的联系

Github上已经有现成的redux-persist包以解决redux持久化问题,但在实际使用过程中,还有很多问题需要解决。具体来说,redux-persist这个包提供的是通用解决方案,也可以用于react.js,如果你要用在react-native中的话,需要指定AsyncStorage,另外,虽然它还额外提供了两个transform插件redux-persist-transform-immutable和redux-persist-immutable,但这两个插件目前使用起来还是有问题没有解决,为了尽快用上redux-persist,可以使用以下方案。

解决

在建立redux store时,除了常规会用到的各种中间件以外,我们需要额外引入redux-persist里的autoRehydrate增强器,然后启动持久化。

Store.ts

import { applyMiddleware, createStore, compose } from 'redux';

import { autoRehydrate } from 'redux-persist';

import createSagaMiddleware from 'redux-saga';

// 中间件,作用:如果不使用该中间件,当我们dispatch一个action时,需要给dispatch函数传入action对象;

// 但如果我们使用了这个中间件,那么就可以传入一个函数,这个函数接收两个参数:dispatch和getState。这个dispatch可以在将来的异步请求完成后使用,对于异步action很有用

import thunk from 'redux-thunk';

import logger from 'redux-logger';

// 引入reducer

import reducer from './reducer';

// 引入持久化配置文件

import ReduxPersist from '../config/ReduxPersist';

// 引入版本变化重新持久化文件

import RehydrationServices from '../config/RehydrationServices';

// 使用redux-thunk中间件,处理异步action,这里则不实用saga中间件

// const sagaMiddleware = createSagaMiddleware();

// let middleware:any = [];

// middleware.push(sagaMiddleware);

let store: any = {};

const createAppropriateStore = createStore;

if (ReduxPersist.active) {

// 如果配置中要求采用持久化

const enhancers = compose(

applyMiddleware(thunk, logger), // 加入thunk中间件和日志中间件

autoRehydrate()

);

store = createAppropriateStore(

reducer,

enhancers

);

// 启动持久化

RehydrationServices.updateReducers(store);

} else {

// 如果配置中不要求采用持久化

store = createStore(

reducer,

applyMiddleware(thunk, logger)

);

}

export default store;

ReduxPersist.ts 持久化配置文件

import { AsyncStorage } from 'react-native';

import immutablePersistenceTransform from '../redux/ImmutablePersistenceTransform';

import { persistentStoreBlacklist } from '../redux/reducer';

const REDUX_PERSIST: any = {

active: true, // 是否采用持久化策略

reducerVersion: '1.0.0', // reducer版本,如果版本不一致,将刷新整个持久化仓库

storeConfig: {

storage: AsyncStorage, // 采用本地异步存储,react-native必须

blacklist: persistentStoreBlacklist, // 从根reducer获取黑名单,黑名单中的reducer不进行持久化保存

transforms: [immutablePersistenceTransform], // 重要,因为redux是immutable不可变的,此处必须将常规数据做变形,否则会失败

}

};

export default REDUX_PERSIST;

RehydrationServices.ts 判断是否替换持久化数据文件

import { AsyncStorage } from 'react-native';

import { persistStore } from 'redux-persist';

import ReduxPersist from './ReduxPersist';

const updateReducers = (store: any) => {

const reducerVersion = ReduxPersist.reducerVersion;

const config = ReduxPersist.storeConfig;

// 按照配置要求自动持久化reducer

persistStore(store, config);

AsyncStorage.getItem('reducerVersion').then((localVersion) => {

// 从本地存储取出reducer版本并比较

if (localVersion !== reducerVersion) {

// 如果本地存储中的reducer版本与配置文件中的reducer版本不同,则需要清理持久化数据

persistStore(store, config, () => {

persistStore(store, config);

}).purge();

// 清理成功,将本地存储中的reducer版本设为配置文件中的reducer版本

AsyncStorage.setItem('reducerVersion', reducerVersion);

}

}).catch(() => AsyncStorage.setItem('reducerVersion', reducerVersion));

}

export default {updateReducers};

reducer/index.ts 合并所有reducers和导出黑名单

// 工具函数,用于组织多个reducer,并返回reducer集合

import { combineReducers } from 'redux';

import configReducer from './configReducer';

import reduxPersister from './reduxPersister'

let reducers = {

config:configReducer,

reduxPersister,

};

// 导出所有reducer

export default combineReducers(reducers);

// 添加persist黑名单,以下这些reducer不需要持久化

export const persistentStoreBlacklist = [

'config',

];

ImmutablePersistenceTransform.ts 数据合并和转换文件

import R from 'ramda';

import Immutable from 'seamless-immutable';

// 将redux中的immutable对象转为普通js对象,以便于持久化存储

const isImmutable = R.has('asMutable');

const convertToJs = (state: any) => state.asMutable({deep: true});

const fromImmutable = R.when(isImmutable, convertToJs);

// 将普通js对象转为immutable不可变,以供redux使用

const toImmutable = (raw: any) => Immutable(raw);

export default {

out: (state: any) => {

// 设置深度合并

state.mergeDeep = R.identity;

// 从仓库中取出,进入内存时,转为immutable不可变

return toImmutable(state);

},

in: (raw: any) => {

// 进入仓库时,将immutable不可变数据转为常规数据

return fromImmutable(raw);

}

};

action.ts 异步action文件

import * as actionTypes from './actionTypes'

export function DemoAction(params:boolean) {

return (dispatch:any, getState:any) => {

dispatch({

type: actionTypes.SOMETEST,

data: params

});

};

};

configReducer.ts

import * as actionTypes from '../action/actionTypes';

const initialState = {

someData: ''

};

export default (state = initialState, action:any) => {

switch (action.type) {

case actionTypes.SOMETEST:

return {

...state,

someData: action.data

}

default:

return state

}

};

参考文章:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值