javascript - Redux persist v6 defaultStateReconciler TypeError: Cannot convert undefined or null to object when first visit web application
问题描述
在开发工具中清除应用程序状态后,或第一次访问站点后,在控制台中收到这些错误。默认状态是无法加载空或未定义的对象。
store 配置 redux-offline,使用 redux-persist v6 和 redux 工具包
我尝试确保我的 createSelector 调用没有 null 初始值。刷新页面会清除错误,并且应用程序的所有后续使用都是无错误的。
autoRehydrate.js:54 Uncaught (in promise) TypeError: Cannot convert undefined or null to object
at Function.keys (<anonymous>)
at defaultStateReconciler (autoRehydrate.js:54)
at autoRehydrate.js:38
at computeNextEntry (<anonymous>:3395:21)
at recomputeStates (<anonymous>:3429:17)
at <anonymous>:3809:22
at Object.dispatch (redux.js:288)
at dispatch (<anonymous>:3856:17)
at middleware.js:28
at redux-toolkit.esm.js:376
at index.js:11
at Object.dispatch (redux-toolkit.esm.js:314)
at Object.dispatch (<anonymous>:14608:80)
at Object.rehydrate (persistStore.js:77)
at _rehydrate (persistReducer.js:61)
at persistReducer.js:90
autoRehydrate.js:54 Uncaught TypeError: Cannot convert undefined or null to object
at Function.keys (<anonymous>)
at defaultStateReconciler (autoRehydrate.js:54)
at autoRehydrate.js:38
at computeNextEntry (<anonymous>:3395:21)
at recomputeStates (<anonymous>:3429:17)
at <anonymous>:3809:22
at Object.dispatch (redux.js:288)
at dispatch (<anonymous>:3856:17)
at middleware.js:28
at redux-toolkit.esm.js:376
at index.js:11
at Object.dispatch (redux-toolkit.esm.js:314)
at Object.dispatch (<anonymous>:14608:80)
at Object.rehydrate (persistStore.js:77)
at _rehydrate (persistReducer.js:61)
at persistReducer.js:67
应用索引:
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import reportWebVitals from "./reportWebVitals";
import "semantic-ui-css/semantic.min.css";
import { BrowserRouter } from "react-router-dom";
import { PersistGate } from "redux-persist/integration/react";
import * as serviceWorkerRegistration from "./serviceWorkerRegistration";
// import redux
import { store, persistor } from "./config/redux/store";
import { Provider } from "react-redux";
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<BrowserRouter>
<App />
</BrowserRouter>
</PersistGate>
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
serviceWorkerRegistration.register();
// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
reportWebVitals();
店铺代码:
import axios, { AxiosRequestConfig } from "axios";
import { AnyAction, Reducer } from "redux";
import {
combineReducers,
configureStore,
StoreEnhancer,
} from "@reduxjs/toolkit";
import { offline } from "@redux-offline/redux-offline";
import config from "@redux-offline/redux-offline/lib/defaults";
import userReducer from "./userSlice";
import noteReducer from "./noteSlice";
import { OfflineAction } from "@redux-offline/redux-offline/lib/types";
import storage from "redux-persist/lib/storage";
import {
persistStore,
persistReducer,
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER,
} from "redux-persist";
// _action variable used for redux-offline
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const effect = (effect: AxiosRequestConfig, _action: OfflineAction) =>
axios({ ...effect, withCredentials: true });
const combinedReducer = combineReducers({
user: userReducer,
notes: noteReducer,
});
export const RESET_BASE = "reset/all";
const rootReducer: Reducer = (state: RootState, action: AnyAction) => {
if (action.type === RESET_BASE) {
state = {} as RootState;
}
return combinedReducer(state, action);
};
const persistConfig = {
key: "root",
storage,
};
const persistedReducer = persistReducer(persistConfig, rootReducer);
export const store = configureStore({
reducer: persistedReducer,
enhancers: [offline({ ...config, effect }) as StoreEnhancer],
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER,
],
},
}),
});
export const persistor = persistStore(store);
export type RootState = ReturnType<typeof store.getState>;
export interface RootStateWithOffline extends RootState {
offline: {
busy: boolean;
lastTransaction: number;
online: boolean;
outbox: Array<ReturnType<typeof effect>>;
retryCount: number;
retryScheduled: boolean;
};
}
export type AppDispatch = typeof store.dispatch;
noteSlice 的初始状态:
export interface NoteState {
array: Array<INote>;
stringMap: StringMap;
tempMap: StringMap;
columnDict: ColumnDict;
filter: string;
search: string;
searchLoading: boolean;
editing?: INote | null;
}
const initialState: NoteState = {
array: [],
stringMap: { arr1: [], arr2: [], arr3: [] },
tempMap: { arr1: [], arr2: [], arr3: [] },
columnDict: {
["col1"]: {
name: "col1",
items: [],
},
["col2"]: {
name: "col2",
items: [],
},
["col3"]: {
name: "col3",
items: [],
},
},
filter: "",
search: "",
searchLoading: false,
};
userSlice 的初始状态:
export interface UserState {
account?: IUser | null;
}
const initialState: UserState = {};
解决方案
推荐阅读
- python - 为什么在连接两个数据帧时concat会向日期添加时间
- laravel - 在 PHPUnit 中调用未定义的方法 decodeResponseJson()
- android - 在底部导航中动态更改片段目的地
- node.js - 在不匹配的 peerDependencies 上强制 npm 安装失败
- javascript - 单击按钮并发送命令以在 xterm.js 终端上执行
- c# - 如何返回一个字符串并在另一个静态 void 中使用它?
- java - org.jboss.msc.service.ServiceNotFoundException:服务服务 jboss.ejb.default-resource-adapter-name-service 未找到
- python - 多进程计算后数据重置
- firebase - Flutter中如何实现动态页面构建?
- python - 如何在 Python 中访问 3d 矩阵的每个元素