67

我正在尝试切换我正在构建的应用程序以使用 Redux Toolkit,并注意到当我从 createStore 切换到 configureStore 时出现此错误:

A non-serializable value was detected in the state, in the path: `varietals.red.0`. Value:, Varietal {
  "color": "red",
  "id": "2ada6486-b0b5-520e-b6ac-b91da6f1b901",
  "isCommon": true,
  "isSelected": false,
  "varietal": "bordeaux blend",
}, 
Take a look at the reducer(s) handling this action type: TOGGLE_VARIETAL.
(See https://redux.js.org/faq/organizing-state#can-i-put-functions-promises-or-other-non-serializable-items-in-my-store-state)

在四处寻找之后,我发现问题似乎出在我的自定义模型上。例如,品种数组是从品种模型创建的:

class Varietal {
  constructor(id, color, varietal, isSelected, isCommon) {
  this.id = id;
  this.color = color;
  this.varietal = varietal;
  this.isSelected = isSelected;
  this.isCommon = isCommon;
 }
}

并使用它映射到一个字符串数组来创建我的 Varietal 数组,该数组进入我的状态:

// my utility function for creating the array
const createVarietalArray = (arr, color, isCommon) =>
  arr.map(v => new Varietal(uuidv5(v, NAMESPACE), color, v, false, isCommon));';

// my array of strings
import redVarietals from '../constants/varietals/red';

// the final array to be exported and used in my state
export const COMMON_RED = createVarietalArray(redVarietals.common.sort(), 'red', true);

当我切换出模型并将数组创建实用程序替换为返回对象的普通数组时,如下所示:

export const createVarietalArray = (arr, color, isCommon) =>
  arr.map(v => ({
    id: uuidv5(v, NAMESPACE),
    color,
    varietal: v,
    isSelected: false,
    isCommon,
  }));

然后那个特殊的减速器的错误消失了,但是我在我的应用程序中都有这些自定义模型,在我开始将它们全部撕掉并重新编码它们只是为了能够使用我想在这里问的 Redux 工具包之前在我这样做之前真的是问题所在......

4

4 回答 4

74

这更有可能是一个问题redux-persistredux-toolkit在其中提供一些默认中间件getDefaultMiddleware

import { getDefaultMiddleware } from '@reduxjs/toolkit';

您可以通过提供 false 标志来禁用每个中间件。去除serializableCheck

const customizedMiddleware = getDefaultMiddleware({
  serializableCheck: false
})

有关详细信息,请查看redux-toolkit 文档

[2021/10/07] 编辑

要了解有关此错误发生原因以及设置serializableCheck为 false 的原因的更多信息,请阅读使用不可序列化数据 | 使用指南redux 工具包文档。

此外,getDefaultMiddleware不推荐使用导出以支持使用回调表单。请参阅未来规划:RTK 2.0?· 问题 #958 · reduxjs/redux-toolkitgetDefaultMiddleware 已弃用 · 问题 #1324 · reduxjs/redux-toolkit了解更多原因。

至于它被替换为什么,请参阅getDefaultMiddleware | Redux Toolkit文档以了解更多信息:

import { configureStore } from '@reduxjs/toolkit'

import rootReducer from './reducer'

const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) => getDefaultMiddleware(),
})
于 2020-08-04T10:20:18.430 回答
46

是的。我们一直告诉 Redux 用户他们不应该在 store 中放置不可序列化的值。Redux Toolkit 专门设计用于在设置 Redux 存储时帮助提供良好的默认值,作为其中的一部分,它包括检查以确保您不会意外更改数据并且不包含不可序列化的值。

根据定义,类实例不是完全可序列化的,因此它正确地将这些实例标记为问题。请重写您的逻辑以将它们传递到商店。

一般来说,React 和 Redux 应用程序应该使用普通的 JS 对象和数组作为数据来编写。您不需要“模型类”。

于 2020-05-10T01:48:09.197 回答
17

React Native我想在redux-persist旁边实现时遇到了这个问题@reduxjs/toolkit,我收到了这个错误:

在此处输入图像描述

然后我通过以下代码修复它:

import {
  combineReducers,
  configureStore,
  getDefaultMiddleware,
} from '@reduxjs/toolkit';
import {
  persistStore,
  persistReducer,
  FLUSH,
  REHYDRATE,
  PAUSE,
  PERSIST,
  PURGE,
  REGISTER,
} from 'redux-persist';
import storage from 'utils/storage'; // in fact it is AsyncStorage
import counter from 'reduxStore/reducers';

const persistConfig = {
  key: 'root',
  storage,
};

const reducer = combineReducers({
  counter,
});

const persistedReducer = persistReducer(persistConfig, reducer);

const store = configureStore({
  reducer: persistedReducer,
  middleware: getDefaultMiddleware({
    serializableCheck: {
      ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
    },
  }),
});

export const persistor = persistStore(store);

export default store;

实际上,这些行对我有帮助,没有它们我得到了上述错误:

middleware: getDefaultMiddleware({
  serializableCheck: {
    ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
  },
}),
于 2020-06-27T13:08:31.653 回答
14

随着getDefaultMiddleware贬值,这可以通过使用来解决

   middleware: getDefaultMiddleware =>
    getDefaultMiddleware({
      serializableCheck: false,
    }),
于 2021-07-24T11:52:25.270 回答