我已经使用传统的react-redux设置配置了redux-persist,如下所示:
onst persistConfig = {
key: 'root',
storage,
whitelist: ['todos'],
};
const persistedReducer = persistReducer(persistConfig, reducer);
const store = createStore(
persistedReducer,
window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
);
const persistor = persistStore(store);
// wrapper
const StateProvider = ({ children }) => {
return (
<Provider store={store}>
<PersistGate loading={<div>Loading...</div>} persistor={persistor}>
{children}
</PersistGate>
</Provider>
);
};
但是,我该如何使用 redux-toolkit 来配置它呢? 到目前为止我已经尝试过这个:
const persistedReducer = persistReducer(persistConfig, todoreducer);
const store = configureStore({
reducer: {
todos: persistedReducer,
},
});
const persistor = persistStore(store);
// wrapper
const StateProvider = ({ children }) => {
return (
<Provider store={store}>
<PersistGate loading={<div>Loading...</div>} persistor={persistor}>
{children}
</PersistGate>
</Provider>
);
};
但是,它不起作用。我无法通过
todos
获得
const todos = useSelector(state => state.todos);
它返回未定义。
store.js
import {configureStore} from '@reduxjs/toolkit';
import storage from 'redux-persist/lib/storage'
import {combineReducers} from "redux";
import { persistReducer } from 'redux-persist'
import thunk from 'redux-thunk'
const reducers = combineReducers({
//...
});
const persistConfig = {
key: 'root',
storage
};
const persistedReducer = persistReducer(persistConfig, reducers);
const store = configureStore({
reducer: persistedReducer,
devTools: process.env.NODE_ENV !== 'production',
middleware: [thunk]
});
export default store;
索引/App.js
import store from './app/store';
import { PersistGate } from 'redux-persist/integration/react'
import { persistStore } from 'redux-persist'
let persistor = persistStore(store);
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App/>
</PersistGate>
</Provider>,
现在 Redux Toolkit 文档 中提供了一份指南,可以帮助您完成此操作,并提供有关清除持久状态和使用 RTK 查询 的建议。
它还有一些您需要复制和粘贴的代码,以忽略操作类型
react-persist
调度。这将阻止它抛出错误消息(当我使用 Expo 运行 React Native 应用程序时,我收到错误 A non-serializable value was detected in an action, in the path: `register`.
)。
在撰写本文时,他们的代码示例如下所示:
import { configureStore } from '@reduxjs/toolkit'
import {
persistStore,
persistReducer,
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER,
} from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import { PersistGate } from 'redux-persist/integration/react'
import App from './App'
import rootReducer from './reducers'
const persistConfig = {
key: 'root',
version: 1,
storage,
}
const persistedReducer = persistReducer(persistConfig, rootReducer)
const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}),
})
let persistor = persistStore(store)
ReactDOM.render(
<Provider store={store}>
<PersistGate loading={null} persistor={persistor}>
<App />
</PersistGate>
</Provider>,
document.getElementById('root')
)
在store.js
import { configureStore } from "@reduxjs/toolkit";
import storage from "redux-persist/lib/storage";
import { persistReducer } from "redux-persist";
import { combineReducers } from "redux";
const persistConfig = {
key: "root",
version: 1,
storage,
// if you do not want to persist this part of the state
blacklist: ['omitedPart']
};
const reducer = combineReducers({
cart: CartReducer,
// not persisting this reducer
omitedPart:OmitReducer
});
// this ensures your redux state is saved to persisted storage whenever it changes
// we pass this to the store
const persistedReducer = persistReducer(persistConfig, reducer);
const store = configureStore({
reducer: persistedReducer,
});
export default store;
在你的根组件中,index.js
import { Provider } from "react-redux";
import store from "./redux/store";
import { PersistGate } from "redux-persist/integration/react";
import { persistStore } from "redux-persist";
let persistor = persistStore(store);
ReactDOM.render(
<React.StrictMode>
<Provider store={store}>
//PersistGate delays the rendering of UI until the persisted state has been retrrieved and saved to redux
<PersistGate persistor={persistor}>
<App />
</PersistGate>
</Provider>
</React.StrictMode>,
document.getElementById("root")
);
当使用带有
stateReconciles
中的 persistConfig
选项的 TypeScript 时,您需要一些类型垫片来避免
unknown
通用推理persistReducer<unknown, AnyAction>
Argument of type 'Reducer<CombinedState<{ ... }>, AnyAction>' is not assignable to parameter of type 'Reducer<unknown, AnyAction>'.
Types of parameters 'state' and 'state' are incompatible.
Type 'unknown' is not assignable to type 'CombinedState<{ ... }>'.ts(2345)
const persistConfig = {
stateReconciles: hardSet as RootState,
}
export type RootState = ReturnType<typeof store.getState> // Type alias 'RootState' circularly references itself.
解决方案是提取类型
CombinedState
,如下:
import type { Reducer } from '@reduxjs/toolkit'
import { configureStore, combineReducers } from '@reduxjs/toolkit'
import { persistStore, persistReducer } from 'redux-persist'
import * as rp from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import hardSet from 'redux-persist/lib/stateReconciler/hardSet'
import createCollectionForm from './slices/CollectionFormSlice'
import auth from './slices/AuthSlice'
const persistConfig = {
key: 'root',
storage,
stateReconciles: hardSet as (inboundState: CombinedState) => CombinedState,
version: 1,
}
type CombinedState = typeof rootReducer extends Reducer<infer U, any> ? U : never
const rootReducer = combineReducers({
auth,
createCollectionForm,
})
const persistedReducer = persistReducer(persistConfig, rootReducer)
export const store = configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [rp.FLUSH, rp.REHYDRATE, rp.PAUSE, rp.PERSIST, rp.PURGE, rp.REGISTER],
},
}),
})
export const persistor = persistStore(store)
export type RootState = ReturnType<typeof store.getState>
export type AppDispatch = typeof store.dispatch
这里是redux-toolkit和redux-persist在文件系统中的解决方案 Expo 使用工具包配置 redux 持久化
我刚刚用完全相同的设置尝试过,它似乎有效。如果有帮助,我会加
"@reduxjs/toolkit": "^1.4.0",
、"redux-persist": "^6.0.0"
和"react-redux": "^7.2.1"
。 HTH.