如何将 Redux-Persist 与 Next.js App Router 结合使用

问题描述 投票:0回答:2

我按照官方文档了解如何使 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 数据?

typescript next.js redux next.js13 redux-persist
2个回答
4
投票

以下是我的实现

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
组件包装整个应用程序。

强烈赞扬这个博客这里,让它看起来更容易。


© www.soinside.com 2019 - 2024. All rights reserved.