Skip to content

rn 里面 redux 的持久化方案

当使用带有stateReconcilesfrom 选项的 TypeScript 时persistConfig,您需要一些类型垫片来避免

  • a)unknown泛型推理
js
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)
  • b) 循环型参考
js
const persistConfig = {
  stateReconciles: hardSet as RootState,
}

export type RootState = ReturnType<typeof store.getState> // Type alias 'RootState' circularly references itself.

解决方案是提取类型CombinedState,如下:

js
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

注意:主要的关键点可能在于必须要使用:combineReducers!!!