Estoy tratando de cambiar una aplicación que estoy construyendo para usar Redux Toolkit, y he notado que aparece este error tan pronto como cambié a configureStore desde createStore:
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)Después de hurgar, encontré que el problema parece estar relacionado con mis modelos personalizados. Por ejemplo, la matriz de variedades se crea a partir de un modelo de variedades:
class Varietal { constructor(id, color, varietal, isSelected, isCommon) { this.id = id; this.color = color; this.varietal = varietal; this.isSelected = isSelected; this.isCommon = isCommon; } }y al usar eso mapeo una matriz de cadenas para crear mi matriz Varietal que entra en mi estado:
// 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);Cuando cambié el modelo y reemplacé la utilidad de creación de matriz con algo que devolvió una matriz simple de objetos como este:
export const createVarietalArray = (arr, color, isCommon) => arr.map(v => ({ id: uuidv5(v, NAMESPACE), color, varietal: v, isSelected: false, isCommon, }));luego apareció el error de desaparecer para ese reductor EN PARTICULAR, sin embargo, tengo estos modelos personalizados en toda mi aplicación y antes de comenzar a extraerlos y recodificarlos simplemente para poder usar el kit de herramientas Redux, quería preguntar aquí si eso es REALMENTE cuál es el problema antes de que hiciera eso...
Si. Siempre les hemos dicho a los usuarios de Redux que no deben poner valores no serializables en la tienda . Redux Toolkit fue diseñado específicamente para ayudar a proporcionar buenos valores predeterminados al configurar una tienda Redux y, como parte de eso, incluye comprobaciones para asegurarse de que no está mutando accidentalmente sus datos y que no está incluyendo valores no serializables.
Las instancias de clase, por definición, no son completamente serializables, por lo que está marcando correctamente esas instancias como un problema. Vuelva a escribir su lógica para no pasarlos a la tienda.
En general, las aplicaciones React y Redux deben escribirse utilizando solo objetos JS simples y matrices como datos. No necesita "clases modelo".
Enfrenté este problema en React Native cuando quería implementar redux-persist persist junto con @reduxjs/toolkit y recibí este error:
Luego lo arreglé con los siguientes códigos:
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;En realidad, estas líneas me ayudan, sin ellas obtuve el error anterior:
middleware: getDefaultMiddleware({ serializableCheck: { ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER], }, }),Esto es más probable que sea un problema de redux-persist . redux-toolkit proporciona pocos middleware predeterminados dentro de getDefaultMiddleware
import { getDefaultMiddleware } from '@reduxjs/toolkit'; Puede deshabilitar cada middleware proporcionando una bandera falsa. Para eliminar serializableCheck
const customizedMiddleware = getDefaultMiddleware({ serializableCheck: false }) Para obtener más información, consulte la documentación redux-toolkit .
[2021/10/07] editar :
Para obtener más información sobre por qué ocurre este error y por qué establecer serializableCheck en falso lo corrige, lea Trabajar con datos no serializables | Documentos del kit de herramientas de redux de la guía de uso .
Además, la exportación getDefaultMiddleware está en desuso a favor del uso de un formulario de devolución de llamada. Consulte Planificación futura: ¿RTK 2.0? · Problema n.º 958 · reduxjs/redux-toolkit y getDefaultMiddleware en desuso · Problema n.º 1324 · reduxjs/redux-toolkit para obtener más información sobre por qué.
En cuanto a con qué se está reemplazando, consulte getDefaultMiddleware | Documentación de Redux Toolkit para obtener más información:
import { configureStore } from '@reduxjs/toolkit' import rootReducer from './reducer' const store = configureStore({ reducer: rootReducer, middleware: (getDefaultMiddleware) => getDefaultMiddleware(), })Con la depreciación de getDefaultMiddleware , esto se puede resolver usando
middleware: getDefaultMiddleware => getDefaultMiddleware({ serializableCheck: false, }),