若要在 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 方法被弃用的问题。