使用 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/[email protected] 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。

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

相关推荐
理查der驾1 小时前
mini-react 第七天:实现useEffect
react.js
孟陬1 小时前
TypeScript 系列:类型更安全的 antd `useForm`
typescript
luoluomo洛尘2 小时前
TypeScript日常类型(9): Literal Types
前端·typescript
巴巴博一3 小时前
前端安全之DOMPurify基础使用
前端·vue.js·安全·typescript·html5
疏狂难除3 小时前
基于SeaORM+MySQL+Tauri2+Vite+React等的CRUD交互项目
前端·react.js·前端框架
lee5764 小时前
用 Vue 3.5 TypeScript 重新开发3年前甘特图的核心组件
vue.js·typescript·甘特图
蒜香拿铁5 小时前
【typescript进阶篇】(第二章) 模块与命名空间
typescript
在广东捡破烂的吴彦祖5 小时前
React关闭缓存标签页刷新页面的hooks
react.js
随笔记5 小时前
用create-react-app脚手架创建react项目报错怎么办
前端·react.js·typescript