Redux Persist Transform Encrypt:baseReducer 不是函数

发布于 2025-01-10 17:30:09 字数 5010 浏览 0 评论 0原文

我能够在所有页面的 localStorage持久我的数据,如下图所示。我创建了两个reducers来处理公共(匿名用户)和公共(匿名用户)的持久数据私人(注册用户)用途。

输入图片此处描述

但不幸的是,当从 redux-persist-transform-encrypt 填充 codes 时出现此错误(如下图所示)

在此处输入图像描述

这里我在 NextJS 项目框架中使用这些

  • @redux/toolkit
  • redux
  • redux-persist
  • redux-persist-tansform-encrypt

这是我的 store.js 位于 /src/redux/store.js

import { configureStore } from '@reduxjs/toolkit'
import { combineReducers } from 'redux'
import {
  FLUSH, PAUSE,
  PERSIST, persistReducer, PURGE,
  REGISTER, REHYDRATE
} from 'redux-persist'
import { encryptTransform } from 'redux-persist-transform-encrypt'
import storage from 'redux-persist/lib/storage'
import globalDynamicPrivate from './slices/globalDynamicPrivate'
import globalDynamicPublic from './slices/globalDynamicPublic'
import { albumSlice } from './slices/album'
import { geoSlice } from './slices/geo'
import { postSlice } from './slices/post'

const encryptor = {
  transforms: [
    encryptTransform({
      secretKey: 'my-super-secret-key',
      onError: function (error) {
        // Handle the error.
        console.log('Error: ', error)
      },
    }),
  ],
}

const persistglobalDynamicPublicConfig = {
  key: 'globalDynamicPublic',
  storage,
}

const persistglobalDynamicPrivateConfig = {
  key: 'globalDynamicPrivate',
  storage,
}

const reducers = combineReducers({
  globalDynamicPublic: persistReducer(
    persistglobalDynamicPublicConfig, 
    { 
      transforms: encryptor
    },
    globalDynamicPublic
  ),
  globalDynamicPrivate: persistReducer(
    persistglobalDynamicPrivateConfig, 
    { 
      transforms: encryptor
    },
    globalDynamicPrivate
  ),
  [albumSlice.reducerPath]: albumSlice.reducer, // RTK Query
  [geoSlice.reducerPath]: geoSlice.reducer, // RTK Query
  [postSlice.reducerPath]: postSlice.reducer, // RTK Query
})

export const store = configureStore({
  reducer: reducers,
  middleware: getDefaultMiddleware => getDefaultMiddleware({
    serializableCheck: {
      ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
    }
  }).concat(albumSlice.middleware).concat(geoSlice.middleware).concat(postSlice.middleware)
})

这些是我的 global reducers

  • 全局公共数据,位于 /src/redux/slices/globalDynamicPublic.js
import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  something: 'this is something',
}

export const globalDynamicPublicSlice = createSlice({
  name: 'globalDynamicPublic',
  initialState,
  // // The reducers field lets us define reducers and generate associated actions
  reducers: {
    setglobalDynamicPublicState: (state, action) => {
      state[action.payload?.name] = action.payload?.value
    }
  }
})

export const { setglobalDynamicPublicState } = globalDynamicPublicSlice.actions;

// The function below is called a selector and allows us to select a value from
// the state. Selectors can also be defined inline where they're used instead of
// in the slice file. For example: useSelector((state: RootState) => state.counter.value)
export const selectglobalDynamicPublicState = (state) => state.globalDynamicPublic

export default globalDynamicPublicSlice.reducer;
  • 全局公共数据位于/src/redux/slices/globalDynamicPrivate.js
import { createSlice } from '@reduxjs/toolkit';

const initialState = {}

export const globalDynamicPrivateSlice = createSlice({
  name: 'globalDynamicPrivate',
  initialState,
  // // The reducers field lets us define reducers and generate associated actions
  reducers: {
    setglobalDynamicPrivateState: (state, action) => {
      state[action.payload?.name] = action.payload?.value
    }
  }
})

export const { setglobalDynamicPrivateState } = globalDynamicPrivateSlice.actions;

// The function below is called a selector and allows us to select a value from
// the state. Selectors can also be defined inline where they're used instead of
// in the slice file. For example: useSelector((state: RootState) => state.counter.value)
export const selectglobalDynamicPrivateState = (state) => state.globalDynamicPrivate

export default globalDynamicPrivateSlice.reducer;

我已经仔细检查了如何导入 &无论使用 export default 还是 export const 导出数据,这似乎都是正确的(因为大多数线程都在解决这个问题)。

I'm able to persist my data in localStorage across all pages as shown in the image below. I've created two reducers to handle persisted data for public(anonymous users) & private(registered users) usages.

enter image description here

But unfortunately got this error (shown in the image below) when populating codes from redux-persist-transform-encrypt

enter image description here

Here I'm using these packages in NextJS project framework:

  • @redux/toolkit
  • redux
  • redux-persist
  • redux-persist-tansform-encrypt

Here is my store.js located in /src/redux/store.js

import { configureStore } from '@reduxjs/toolkit'
import { combineReducers } from 'redux'
import {
  FLUSH, PAUSE,
  PERSIST, persistReducer, PURGE,
  REGISTER, REHYDRATE
} from 'redux-persist'
import { encryptTransform } from 'redux-persist-transform-encrypt'
import storage from 'redux-persist/lib/storage'
import globalDynamicPrivate from './slices/globalDynamicPrivate'
import globalDynamicPublic from './slices/globalDynamicPublic'
import { albumSlice } from './slices/album'
import { geoSlice } from './slices/geo'
import { postSlice } from './slices/post'

const encryptor = {
  transforms: [
    encryptTransform({
      secretKey: 'my-super-secret-key',
      onError: function (error) {
        // Handle the error.
        console.log('Error: ', error)
      },
    }),
  ],
}

const persistglobalDynamicPublicConfig = {
  key: 'globalDynamicPublic',
  storage,
}

const persistglobalDynamicPrivateConfig = {
  key: 'globalDynamicPrivate',
  storage,
}

const reducers = combineReducers({
  globalDynamicPublic: persistReducer(
    persistglobalDynamicPublicConfig, 
    { 
      transforms: encryptor
    },
    globalDynamicPublic
  ),
  globalDynamicPrivate: persistReducer(
    persistglobalDynamicPrivateConfig, 
    { 
      transforms: encryptor
    },
    globalDynamicPrivate
  ),
  [albumSlice.reducerPath]: albumSlice.reducer, // RTK Query
  [geoSlice.reducerPath]: geoSlice.reducer, // RTK Query
  [postSlice.reducerPath]: postSlice.reducer, // RTK Query
})

export const store = configureStore({
  reducer: reducers,
  middleware: getDefaultMiddleware => getDefaultMiddleware({
    serializableCheck: {
      ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
    }
  }).concat(albumSlice.middleware).concat(geoSlice.middleware).concat(postSlice.middleware)
})

These are my global reducers

  • global public data located in /src/redux/slices/globalDynamicPublic.js
import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  something: 'this is something',
}

export const globalDynamicPublicSlice = createSlice({
  name: 'globalDynamicPublic',
  initialState,
  // // The reducers field lets us define reducers and generate associated actions
  reducers: {
    setglobalDynamicPublicState: (state, action) => {
      state[action.payload?.name] = action.payload?.value
    }
  }
})

export const { setglobalDynamicPublicState } = globalDynamicPublicSlice.actions;

// The function below is called a selector and allows us to select a value from
// the state. Selectors can also be defined inline where they're used instead of
// in the slice file. For example: useSelector((state: RootState) => state.counter.value)
export const selectglobalDynamicPublicState = (state) => state.globalDynamicPublic

export default globalDynamicPublicSlice.reducer;
  • global public data located in /src/redux/slices/globalDynamicPrivate.js
import { createSlice } from '@reduxjs/toolkit';

const initialState = {}

export const globalDynamicPrivateSlice = createSlice({
  name: 'globalDynamicPrivate',
  initialState,
  // // The reducers field lets us define reducers and generate associated actions
  reducers: {
    setglobalDynamicPrivateState: (state, action) => {
      state[action.payload?.name] = action.payload?.value
    }
  }
})

export const { setglobalDynamicPrivateState } = globalDynamicPrivateSlice.actions;

// The function below is called a selector and allows us to select a value from
// the state. Selectors can also be defined inline where they're used instead of
// in the slice file. For example: useSelector((state: RootState) => state.counter.value)
export const selectglobalDynamicPrivateState = (state) => state.globalDynamicPrivate

export default globalDynamicPrivateSlice.reducer;

I've double checked how I import & export data whether using export default or export constand it seems to be true (Since most of threads out there addressing this issue).

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文