使用 Redux Toolkit封装一个模块化的 store

使用 Redux Toolkit(@reduxjs/toolkit v2.6.1)封装一个模块化的 store,并实现工程化的 Redux 管理,需要考虑模块化、可扩展性和清晰的文件结构。以下是一个完整的实现方案,适用于模块化管理的 Redux 项目。


项目结构

假设你的项目结构如下:

python 复制代码
src/
├── store/
│   ├── index.ts           # store 配置入口
│   ├── rootReducer.ts     # 根 reducer 组合
│   ├── hooks.ts           # 自定义 hooks
│   └── modules/           # 模块化切片目录
│       ├── counter/       # 示例模块:counter
│       │   ├── slice.ts   # counter 的 slice
│       │   └── types.ts   # counter 的类型定义
│       └── user/          # 示例模块:user
│           ├── slice.ts   # user 的 slice
│           └── types.ts   # user 的类型定义
├── App.tsx                # 应用入口
└── ...

实现步骤

1. 安装依赖

确保已安装 Redux Toolkit 和 React-Redux:

bash 复制代码
npm install @reduxjs/toolkit@2.6.1 react-redux

2. 创建模块化切片(以 counter 和 user 为例)

counter 模块:src/store/modules/counter/slice.ts

typescript 复制代码
import { createSlice, PayloadAction } from '@reduxjs/toolkit';

// 状态类型
export interface CounterState {
  value: number;
}

const initialState: CounterState = {
  value: 0,
};

/**
 * Counter 模块的 Redux slice
 */
const counterSlice = createSlice({
  name: 'counter',
  initialState,
  reducers: {
    increment: (state) => {
      state.value += 1;
    },
    decrement: (state) => {
      state.value -= 1;
    },
    incrementByAmount: (state, action: PayloadAction<number>) => {
      state.value += action.payload;
    },
  },
});

// 导出 actions 和 reducer
export const { increment, decrement, incrementByAmount } = counterSlice.actions;
export default counterSlice.reducer;

user 模块:src/store/modules/user/slice.ts

typescript 复制代码
import { createSlice, PayloadAction } from '@reduxjs/toolkit';

// 状态类型
export interface UserState {
  name: string;
  isLoggedIn: boolean;
}

const initialState: UserState = {
  name: '',
  isLoggedIn: false,
};

/**
 * User 模块的 Redux slice
 */
const userSlice = createSlice({
  name: 'user',
  initialState,
  reducers: {
    login: (state, action: PayloadAction<string>) => {
      state.name = action.payload;
      state.isLoggedIn = true;
    },
    logout: (state) => {
      state.name = '';
      state.isLoggedIn = false;
    },
  },
});

// 导出 actions 和 reducer
export const { login, logout } = userSlice.actions;
export default userSlice.reducer;

3. 组合根 Reducer(src/store/rootReducer.ts

将所有模块的 reducer 组合成一个根 reducer:

typescript 复制代码
import { combineReducers } from '@reduxjs/toolkit';
import counterReducer from './modules/counter/slice';
import userReducer from './modules/user/slice';

const rootReducer = combineReducers({
  counter: counterReducer,
  user: userReducer,
});

export type RootState = ReturnType<typeof rootReducer>;
export default rootReducer;
  • RootState 类型用于后续类型推导,确保类型安全。

4. 配置 Store(src/store/index.ts

使用 configureStore 创建一个模块化的 store:

typescript 复制代码
import { configureStore } from '@reduxjs/toolkit';
import rootReducer from './rootReducer';

const store = configureStore({
  reducer: rootReducer,
  middleware: (getDefaultMiddleware) =>
    getDefaultMiddleware({
      serializableCheck: false, // 可选:关闭序列化检查(如果需要非序列化状态)
    }),
  devTools: process.env.NODE_ENV !== 'production', // 开发环境启用 Redux DevTools
});

export default store;

// 导出类型用于 hooks
export type AppDispatch = typeof store.dispatch;
  • configureStore 自带默认中间件(如 redux-thunk),并支持 Redux DevTools。
  • AppDispatch 类型用于类型安全的 dispatch

5. 创建自定义 Hooks(src/store/hooks.ts

为了方便在 React 组件中使用类型安全的 Redux,创建自定义 hooks:

typescript 复制代码
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
import { RootState, AppDispatch } from '../store';

// 类型安全的 useSelector
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

// 类型安全的 useDispatch
export const useAppDispatch = () => useDispatch<AppDispatch>();

6. 在应用中集成(src/App.tsx

将 store 提供给 React 应用,并使用模块化的 Redux:

typescript 复制代码
import React from 'react';
import { Provider } from 'react-redux';
import store from './store';
import Counter from './Counter';
import User from './User';

const App: React.FC = () => {
  return (
    <Provider store={store}>
      <div>
        <h1>Redux Toolkit Modular Demo</h1>
        <Counter />
        <User />
      </div>
    </Provider>
  );
};

export default App;

示例组件:src/Counter.tsx

typescript 复制代码
import React from 'react';
import { useAppSelector, useAppDispatch } from './store/hooks';
import { increment, decrement, incrementByAmount } from './store/modules/counter/slice';

const Counter: React.FC = () => {
  const count = useAppSelector((state) => state.counter.value);
  const dispatch = useAppDispatch();

  return (
    <div>
      <h2>Counter: {count}</h2>
      <button onClick={() => dispatch(increment())}>Increment</button>
      <button onClick={() => dispatch(decrement())}>Decrement</button>
      <button onClick={() => dispatch(incrementByAmount(5))}>Add 5</button>
    </div>
  );
};

export default Counter;

示例组件:src/User.tsx

typescript 复制代码
import React from 'react';
import { useAppSelector, useAppDispatch } from './store/hooks';
import { login, logout } from './store/modules/user/slice';

const User: React.FC = () => {
  const { name, isLoggedIn } = useAppSelector((state) => state.user);
  const dispatch = useAppDispatch();

  return (
    <div>
      <h2>User: {isLoggedIn ? name : 'Not logged in'}</h2>
      <button onClick={() => dispatch(login('Alice'))}>Login as Alice</button>
      <button onClick={() => dispatch(logout())}>Logout</button>
    </div>
  );
};

export default User;

特点与优势

  1. 模块化管理

    • 每个功能模块(如 counteruser)都有独立的 slice 文件,包含状态、reducer 和 actions。
    • 通过 rootReducer 组合所有模块,保持清晰的层次结构。
  2. 类型安全

    • 使用 TypeScript 定义状态和 dispatch 类型,避免类型错误。
    • 自定义 useAppSelectoruseAppDispatch 提供类型支持。
  3. Redux Toolkit v2.6.1 特性

    • 使用 createSlice 简化 reducer 和 action 创建。
    • configureStore 自带默认中间件和 DevTools 支持。
    • 支持异步逻辑(可通过 createAsyncThunk 扩展)。
  4. 可扩展性

    • 添加新模块时,只需创建新的 slice 并在 rootReducer 中注册即可。

扩展建议

  • 异步逻辑 :使用 createAsyncThunk 处理 API 请求。

    typescript 复制代码
    import { createAsyncThunk } from '@reduxjs/toolkit';
    export const fetchUser = createAsyncThunk('user/fetch', async (id: string) => {
      const response = await fetch(`/api/user/${id}`);
      return response.json();
    });
  • 中间件:根据需要添加自定义中间件(如日志中间件)。

  • RTK Query:如果需要数据获取和缓存,可以集成 Redux Toolkit Query。

这个封装方案已经完全模块化,适用于中小型到大型项目。你可以根据具体需求调整目录结构或添加更多功能。如果有其他问题或需要优化某个部分,请告诉我!

相关推荐
前端小盆友1 小时前
从零实现一个GPT 【React + Express】--- 【2】实现对话流和停止生成
前端·gpt·react.js
一生躺平的仔1 小时前
TypeScript入门(九)装饰器:TypeScript的"元编程超能力"
typescript
MiyueFE2 小时前
让我害怕的 TypeScript 类型 — — 直到我学会了这 3 条规则
前端·typescript
OLong2 小时前
2025年最强React插件,支持大量快捷操作
前端·react.js·visual studio code
摸鱼仙人~2 小时前
重塑智能体决策路径:深入理解 ReAct 框架
前端·react.js·前端框架
namehu2 小时前
浏览器中的扫码枪:从需求到踩坑再到优雅解决
前端·react.js
杨进军2 小时前
React 使用 MessageChannel 实现异步更新
react.js
前端拿破轮2 小时前
😭😭😭看到这个快乐数10s,我就知道快乐不属于我了🤪
算法·leetcode·typescript
前端_ID林2 小时前
每个开发人员都应该知道的 TypeScript 技巧
typescript
namehu2 小时前
浏览器中的打印魔法:Lodop与系统打印机
前端·react.js