جافاسكريبت - تلقي خطأ "تم اكتشاف قيمة غير قابلة للتسلسل في الحالة" عند استخدام Redux Toolkit - ولكن ليس مع Redux العادي
أنا أحاول تحويل تطبيق أعمل على بنائه لاستخدام 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 Toolkit أردت أن أسأل هنا إذا كان هذا هو بالفعل المشكلة قبل أن أفعل ذلك...
الإجابة رقم 1
من المرجح أن تكون هذه مشكلة من redux-persist. يوفر redux-toolkit بعض الوسائط الافتراضية ضمن getDefaultMiddleware الخاصة به
import { getDefaultMiddleware } from '@reduxjs/toolkit';
يمكنك تعطيل كل برنامج وسيط عن طريق توفير علم خاطئ. لإزالة serializableCheck
const customizedMiddleware = getDefaultMiddleware({
serializableCheck: false
})
للتفاصيل تحقق من وثائق redux-toolkit.
[2021/10/07] تعديل:
لتعلّم المزيد حول سبب حدوث هذا الخطأ، ولماذا يؤدي ضبط serializableCheck على false إلى إصلاحه، اقرأ العمل مع البيانات غير القابلة للتسلسل | دليل الاستخدام في مستندات Redux Toolkit.
بالإضافة إلى ذلك، يتم إهمال التصدير getDefaultMiddleware لصالح استخدام شكل الاستدعاء. راجع التخطيط المستقبلي: RTK 2.0؟ - المشكلة #958 - reduxjs/redux-toolkit و getDefaultMiddleware مهمل - المشكلة #1324 - reduxjs/redux-toolkit لمعرفة المزيد عن السبب.
أما بالنسبة لما سيتم استبداله به، انظر توثيق getDefaultMiddleware | Redux Toolkit لمعرفة المزيد:
import { configureStore } from '@reduxjs/toolkit'
import rootReducer from './reducer'
const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) => getDefaultMiddleware(),
})
الإجابة رقم 2
نعم. لقد أخبرنا مستخدمي Redux دائمًا أنهم يجب ألا يضعوا قيمًا غير قابلة للتسلسل في المخزن. تم تصميم Redux Toolkit خصيصًا لمساعدة المستخدمين على توفير إعدادات افتراضية جيدة عند إعداد مخزن Redux، وكجزء من ذلك، يتضمن Toolkit فحوصات للتأكد من أنك لا تقوم بتغيير بياناتك عن طريق الخطأ وأنك لا تدرج قيمًا غير قابلة للتسلسل.
مثيلات الفئة حسب التعريف ليست قابلة للتسلسل بالكامل، لذا فهي تشير بشكل صحيح إلى أن هذه المثيلات تمثل مشكلة. يرجى إعادة كتابة منطقك بحيث لا تمرر هذه المثيلات إلى المخزن.
بشكل عام، يجب كتابة تطبيقات React وRedux باستخدام كائنات وآلام جافاسكت عادية فقط كبيانات. لا تحتاج إلى "فئات نموذجية".
الإجابة رقم 3
مع استهلاك getDefaultMiddleware، يمكن حل هذا ب
middleware: getDefaultMiddleware =>
getDefaultMiddleware({
serializableCheck: false,
}),
الإجابة رقم 4
واجهت هذه المشكلة على 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],
},
}),
الإجابة #5
يظهر هذا المثال استثناء برنامج فحص الحالة القابلة للتسلسل وأدخل وصف الرابط هنا
const store = configureStore({
reducer: rootReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: false,
}),
})
الإجابة #6
تحقق من مستندات RTK حول كيفية إعداده مع Redux Persist.
https://redux-toolkit.js.org/usage/usage-guide#use-with-redux-persist
بشكل أساسي، إنها مجرد هذا السطر:
middleware: getDefaultMiddleware =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
})
والذي يكون في استدعاء configureStore.
أيضًا، تحتاج هذا:
import {
persistStore,
persistReducer,
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER,
} from 'redux-persist'
