使用Redux-persist + Redux Toolkit + Nextjs 实现Redux持久化(Tsx版)

1,727 阅读3分钟

若要在 Next.js 中使用 redux-persist 和 @reduxjs/toolkit 实现 Redux 的持久化,可以按照以下步骤进行设置:

1. 安装依赖:

```bash
npm install redux react-redux redux-persist next-redux-wrapper
```

2. 创建 Redux Store:

在你的项目中创建一个 `store` 文件夹,并在其中创建 `index.ts` 文件来配置 Redux Store。

```typescript
// store/index.ts

import { configureStore, getDefaultMiddleware } from '@reduxjs/toolkit';
import { persistReducer, persistStore } from 'redux-persist';
import storage from 'redux-persist/lib/storage';
import rootReducer from './reducers';

const persistConfig = {
  key: 'root',
  storage,
  whitelist: ['user'], // 只持久化 'user' 状态
};

const persistedReducer = persistReducer(persistConfig, rootReducer);

const makeStore = () => {
  const store = configureStore({
    reducer: persistedReducer,
    middleware: getDefaultMiddleware({
      serializableCheck: false, // 忽略非序列化的 action,以便与 redux-persist 兼容
    }),
  });

  const persistor = persistStore(store);
  return { store, persistor };
};

export default makeStore;
```

3. 创建 Redux Reducers:

在 `store` 文件夹中创建一个 `reducers.ts` 文件,并在其中编写你的 Redux Reducers。

```typescript
// store/reducers.ts

import { combineReducers } from 'redux';
import { userReducer } from './userSlice'; // 假设你有一个名为 userSlice 的切片

const rootReducer = combineReducers({
  // 将你的 Reducers 添加到这里
  user: userReducer,
});

export default rootReducer;
```

4. 创建 Redux 切片:

在 `store` 文件夹中创建一个 `userSlice.ts` 文件(假设你的状态为 user),并在其中编写你的 Redux 切片。

```typescript
// store/userSlice.ts

import { createSlice } from '@reduxjs/toolkit';

const userSlice = createSlice({
  name: 'user',
  initialState: { name: '', email: '' },
  reducers: {
    setUser: (state, action) => {
      // 处理设置用户信息的 action
      state.name = action.payload.name;
      state.email = action.payload.email;
    },
  },
});

export const { setUser } = userSlice.actions;
export default userSlice.reducer;
```

5. 在页面中使用 Redux:

在你的页面组件中,使用 `useSelector` 和 `useDispatch` 钩子来访问和更新 Redux Store 中的状态。

```tsx
// pages/index.tsx

import { useSelector, useDispatch } from 'react-redux';
import { withRedux, withReduxPersist } from '../store';
import { setUser } from '../store/userSlice';

function HomePage() {
  const user = useSelector((state) => state.user);
  const dispatch = useDispatch();

  const handleSetUser = () => {
    dispatch(setUser({ name: 'John Doe', email: 'john@example.com' }));
  };

  return (
    <div>
      <h1>User: {user.name}</h1>
      <button onClick={handleSetUser}>Set User</button>
    </div>
  );


}

export default withRedux(withReduxPersist(HomePage));
```

6. 配置 Next.js 应用程序:

创建一个 `withRedux.tsx` 文件来封装 Next.js 应用程序,将 Redux Provider 和 Redux Persist 提供器添加到应用程序中。

```tsx
// withRedux.tsx

import React from 'react';
import { Provider } from 'react-redux';
import { PersistGate } from 'redux-persist/integration/react';
import makeStore from './store';

const { store, persistor } = makeStore();

export const withRedux = (WrappedComponent: React.ComponentType) => {
  const WithRedux = (props: any) => (
    <Provider store={store}>
      <WrappedComponent {...props} />
    </Provider>
  );

  return WithRedux;
};

export const withReduxPersist = (WrappedComponent: React.ComponentType) => {
  const WithReduxPersist = (props: any) => (
    <PersistGate persistor={persistor}>
      <WrappedComponent {...props} />
    </PersistGate>
  );

  return WithReduxPersist;
};
```

7. 在 Next.js 页面中使用 Redux:

在页面组件中,使用 `withRedux` 和 `withReduxPersist` 高阶组件包装你的页面组件,以便将 Redux Store 和持久化功能集成到应用程序中。

```tsx
// pages/index.tsx

import { useSelector, useDispatch } from 'react-redux';
import { withRedux, withReduxPersist } from '../withRedux';
import { setUser } from '../store/userSlice';

function HomePage() {
  const user = useSelector((state) => state.user);
  const dispatch = useDispatch();

  const handleSetUser = () => {
    dispatch(setUser({ name: 'John Doe', email: 'john@example.com' }));
  };

  return (
    <div>
      <h1>User: {user.name}</h1>
      <button onClick={handleSetUser}>Set User</button>
    </div>
  );
}

export default withRedux(withReduxPersist(HomePage));
```

在上述代码中,`withRedux` 和 `withReduxPersist` 高阶组件分别将 Redux Store 和 Redux Persist 提供器添加到应用程序中。

通过按照以上步骤进行设置,你将能够在 Next.js 中使用 redux-persist 和 @reduxjs/toolkit 实现 Redux 的持久化。Redux Store 中指定的状态将被持久化,并在页面刷新后保留其值。

后记:

在新版本中getDefaultMiddleware 方法被标记为弃用(deprecated)。

可以使用 @reduxjs/toolkit 中,可以使用 configureStore 函数的 middleware 选项来替代 getDefaultMiddleware

更新后的代码示例:

import { configureStore } from '@reduxjs/toolkit';
import { persistStore } from 'redux-persist';
import rootReducer from './reducers';

const makeStore = () => {
  const store = configureStore({
    reducer: rootReducer,
    middleware: (getDefaultMiddleware) => getDefaultMiddleware({
      serializableCheck: false, // 忽略非序列化的 action,以便与 redux-persist 兼容
    }),
  });

  const persistor = persistStore(store);
  return { store, persistor };
};

export default makeStore;

在上述代码中,我们使用 configureStore 函数的 middleware 选项,并传递一个回调函数,该函数接受 getDefaultMiddleware 作为参数,并返回带有所需配置的中间件数组。

通过这种方式,你可以使用最新的 @reduxjs/toolkit 版本,同时解决 getDefaultMiddleware 方法被弃用的问题。