我按照官方文档了解如何使 redux 与 Next.js 应用程序路由器一起使用。一切都按预期进行,但现在我试图用
redux-persist
保存数据,事情变得非常混乱。
redux官方文档中没有示例。我不知道如何处理这样的事实:我通过使用包装在
configureStore
函数中的 makeStore
创建每个请求的 Redux 存储(官方 Redux 文档推荐的方法,将 Redux 与 Next 应用程序路由器一起使用)。
我什至无法将
makeStore
传递给 persistStore
方法而不出现类型错误:
Argument of type '() => EnhancedStore<{ user: userInterface; } & PersistPartial, UnknownAction, Tuple<[StoreEnhancer<{ dispatch: ThunkDispatch<{ user: userInterface; } & PersistPartial, undefined, UnknownAction>; }>, StoreEnhancer]>>' is not assignable to parameter of type 'Store<any, UnknownAction, unknown>'
这就是我目前所处的位置:
store.js:
import {
persistStore,
persistReducer,
FLUSH,
REHYDRATE,
PAUSE,
PERSIST,
PURGE,
REGISTER,
} from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import { configureStore, combineReducers } from '@reduxjs/toolkit'
import {userReducer} from "./user/userSlice"
const combinedReducers = combineReducers({
user: userReducer,
})
const persistedReducer = persistReducer(
{
key: 'root',
storage,
whitelist: ['user'],
},
combinedReducers
)
export const makeStore = () => {
return configureStore({
reducer: persistedReducer,
middleware: (getDefaultMiddleware) =>
getDefaultMiddleware({
serializableCheck: {
ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER],
},
}),
})
}
export const persistor = persistStore(makeStore)
export type AppStore = ReturnType<typeof makeStore>
export type RootState = ReturnType<AppStore['getState']>
export type AppDispatch = AppStore['dispatch']
店铺供应商:
"use client";
import { useRef } from "react";
import { Provider } from "react-redux";
import { makeStore, AppStore } from "../redux/store";
export default function StoreProvider({
children,
}: {
children: React.ReactNode;
}) {
const storeRef = useRef<AppStore>();
if (!storeRef.current) {
// Create the store instance the first time this renders
storeRef.current = makeStore();
}
return <Provider store={storeRef.current}>{children}</Provider>;
}
布局.js
import type { Metadata } from "next";
import "./globals.css";
import StoreProvider from "./StoreProvider";
export const metadata: Metadata = {
title: "App",
description: "App Desription",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<StoreProvider>{children}</StoreProvider>
</body>
</html>
);
}
考虑到每个请求创建存储的必要性,如何调整代码来持久保存 Redux 数据?
以下是我的实现
store.ts
import { combineReducers, configureStore } from '@reduxjs/toolkit'
import { persistStore, persistReducer } from 'redux-persist'
import storage from 'redux-persist/lib/storage'
import userSlice from './features/login/userSlice'
const persistConfig = {
key: 'persist',
storage,
}
const rootReducer = combineReducers({
user: userSlice,
})
const makeConfiguredStore = () =>
configureStore({
reducer: rootReducer,
})
export const makeStore = () => {
const isServer = typeof window === 'undefined'
if (isServer) {
return makeConfiguredStore()
} else {
const persistedReducer = persistReducer(persistConfig, rootReducer)
let store: any = configureStore({
reducer: persistedReducer,
})
store.__persistor = persistStore(store)
return store
}
}
export type AppStore = ReturnType<typeof makeStore>
export type RootState = ReturnType<AppStore['getState']>
export type AppDispatch = AppStore['dispatch']
我们需要了解 Next.js 中的服务器和客户端模式,因为我们最终不需要服务器端的持久化。
以下是我的实现
StoreProvider.tsx
'use client'
import { useRef } from 'react'
import { Provider } from 'react-redux'
import { makeStore, AppStore } from '../lib/store'
import { PersistGate } from 'redux-persist/integration/react'
export default function StoreProvider({
children,
}: {
children: React.ReactNode
}) {
const storeRef = useRef<AppStore>()
if (!storeRef.current) {
// Create the store instance the first time this renders
storeRef.current = makeStore()
}
return (
<Provider store={storeRef.current}>
<PersistGate loading={null} persistor={storeRef.current.__persistor}>
{children}
</PersistGate>
</Provider>
)
}
使用 ref 维护渲染之间的
store
状态,然后您可以使用此 StateProvider
组件包装整个应用程序。
强烈赞扬这个博客这里,让它看起来更容易。