开箱即用的React数据存储持久化方案:🐙localforage+makePersistable🐙
使用localforage结合makePersistable是一种在React应用中实现数据持久化的方案。localforage是一个简单易用的IndexedDB封装库,使得在浏览器中使用持久化存储变得更加容易。而makePersistable是一个用于将React组件状态持久化到localforage的库。
本项目是基于mobx开发。
话不多说,直接开干。
方法封装
import localforage from 'localforage'
import CryptoJS from 'crypto-js'
// 全局不动配置项 只做导出不做修改
// const CommonProjectConfig: {
// HOME_URL: string
// TABS_BLACK_LIST: string[]
// APP_TEST: { TIME_MAX: number; TIME_DEFAULT: number; CLICK_MAX: number; CLICK_DEFAULT: number }
// APP_KEY: string
// APP_IV: string
// APP_ID: string
// } = {
// // 首页路由地址(默认)
// HOME_URL: '/HomePage',
// // Tabs(黑名单地址,不需要添加到 tabs 的路由地址,暂时没用)
// TABS_BLACK_LIST: ['/403', '/404', '/500', '/layout', '/login', '/dataScreen'],
// // 灰度环境相关配置
// APP_TEST: {
// TIME_MAX: 60,
// TIME_DEFAULT: 1,
// CLICK_MAX: 10,
// CLICK_DEFAULT: 1
// },
// // localStorage加密相关 、 服务端请求加密相关
// APP_KEY: '',
// APP_IV: '',
// APP_ID: ''
// }
// export default CommonProjectConfig
/**
* 加密
* @param data
* @param output
*/
export const encrypt = (data: string, output?: any) => {
const dataHex = CryptoJS.enc.Utf8.parse(data)
const encrypted = CryptoJS.AES.encrypt(dataHex, CryptoJS.enc.Utf8.parse(CommonProjectConfig.APP_KEY), {
iv: CryptoJS.enc.Utf8.parse(CommonProjectConfig.APP_IV),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
return encrypted.ciphertext.toString(output)
}
/**
* 解密
* @param data
*/
export const decrypt = (data: string | null) => {
const encryptedHex = CryptoJS.enc.Hex.parse(data)
const encryptedHexStr = CryptoJS.enc.Base64.stringify(encryptedHex)
const decrypted = CryptoJS.AES.decrypt(encryptedHexStr, CryptoJS.enc.Utf8.parse(CommonProjectConfig.APP_KEY), {
iv: CryptoJS.enc.Utf8.parse(CommonProjectConfig.APP_IV),
mode: CryptoJS.mode.CBC,
padding: CryptoJS.pad.Pkcs7
})
const decryptedStr = decrypted.toString(CryptoJS.enc.Utf8)
return decryptedStr.toString()
}
export const handleLocalforage = {
config: (options?: LocalForageOptions) => localforage.config(options || {}),
setItem: (key: string, value: string, encrypted: boolean = false) =>
localforage.setItem(key, encrypted ? encrypt(value) : value),
getItem: async (key: string, decrypted: boolean = false) => {
try {
const value = (await localforage.getItem(key)) as string
console.log('value: ', value)
return decrypted ? decrypt(value) : value
} catch (error) {
console.error('Error retrieving data from localforage:', error)
return null
}
},
removeItem: (key: string) => localforage.removeItem(key),
clear: () => localforage.clear(),
createInstance: (name: string) =>
localforage.createInstance({
name
})
}
mobx中存储
import { makeAutoObservable, runInAction } from 'mobx'
import { makePersistable } from 'mobx-persist-store'
import { getCommonEnumApi } from '@/apis/modules/common/common.api'
import { setResult, handleLocalforage } from '@edison/common/core/utils/util'
class CommonStore {
enumObj: any = {} // 获取对应模块枚举类时 使用enumObj.模块名?.枚举类 建议带上? 防止undefined造成代码报错
constructor() {
makeAutoObservable(this)
makePersistable(this, {
name: 'enumObj', // 保存的name,用于在storage中的名称标识,只要不和storage中其他名称重复就可以
properties: ['enumObj'],
// 要保存的字段,这些字段会被保存在name对应的storage中,注意:不写在这里面的字段将不会被保存,
// 刷新页面也将丢失:get字段例外。get数据会在数据返回后再自动计算
storage: handleLocalforage // 保存的位置:看自己的业务情况选择,可以是localStorage,sessionstorage
})
}
async getCommonEnum(data: any) {
const resultObj = {
api: getCommonEnumApi,
result: 'enumObj',
apiParams: data
}
await setResult.call(this, resultObj)
// localStorage.setItem('enumObj', JSON.stringify(this.enumObj))
}
}
export default new CommonStore()
使用
按照store里的数据正常使用
// SomeComponent.tsx
import { useStores } from '@/stores'
const SomeComponent = (props) => {
const { MyStore } = useStores()
console.log(MyStore.enumList)
return <div>SomeComponent</div>
}
参考文章
转载自:https://juejin.cn/post/7375083502411431948