Redux Toolkit (RTK) + TypeScript

文章目录

Redux 的三个核心阶段( 定义 Slice -> 配置 Store -> 组件使用


第一阶段:定义数据切片

这一步是业务逻辑的核心。

  • 1. 定义 IState: 为了类型安全,必须定义。
  • 2. initialState:
  • 3. createAsyncThunk: 专门处理 HTTP 请求。
  • 4. createSlice:
  • 5. reducers vs extraReducers :
    • 补充reducers 处理同步(如:toggleMenu),extraReducers 监听异步 Thunk 的状态(pending, fulfilled, rejected)。
    • 注意 :在 TS 中,extraReducers 现在推荐使用 builder callback 写法(builder.addCase(...)),这样类型推断最准确。
  • 6. Export : 导出 actions 给 UI 用,导出 reducer 给 Store 用。

第二阶段:配置全局 Store

这一步是把分散的 Slice 组装成大脑。

  • 7. combineReducers :
    • 这一步在 RTK 中是可选 的。直接传一个对象,configureStore 底层会自动帮你调 combineReducers
    • 写法const rootReducer = combineReducers({ user, order })
    • 简化写法reducer: { user: userReducer, order: orderReducer }(推荐,少写一行代码)。
  • 8. configureStore: 这是 RTK 的核心,自动开启了 Redux DevTools。
  • 9. Export Hooks : 非常重要!
    • 你提到了 useAppDispatchuseAppSelector,这非常关键。
    • 原因 :原生的 useDispatch 不知道你 Thunk 的类型,原生的 useSelector 不知道你 RootState 的结构。二次封装后,你在组件里写代码会有完美的 TS 提示。

第三阶段:组件使用

这一步是 UI 与数据交互。

  • 10. useAppDispatch :
    • 术语纠正 :我们通过 dispatch 触发 action,而不是直接调用 reducers。Reducers 是在后台听到 action 后执行的。
  • **11. useAppSelector:
    • 补充:它会自动订阅更新。只要 Store 里的数据变了,组件会自动 Re-render(重新渲染),不需要你手动干预。
  • 12. useEffect 监听 :
    • 场景 A(自动更新视图) :不需要 useEffectuseAppSelector 拿到的数据变了,页面这块 DOM 自动就变了。
    • 场景 B(副作用) :比如"登录成功后跳转页面"或者"弹出成功提示",这种才需要用 useEffect 监听状态变化。

极简代码模板

1. Slice (userSlice.ts)
typescript 复制代码
// Step 1
interface UserState {
  loading: boolean;
  data: any;
}
// Step 2
const initialState: UserState = { loading: false, data: null };

// Step 3
export const loginUser = createAsyncThunk('user/login', async (params) => {
  return await api.login(params);
});

// Step 4
const userSlice = createSlice({
  name: 'user',
  initialState,
  // Step 5: 同步
  reducers: {
    logout: (state) => { state.data = null; }
  },
  // Step 5: 异步 (Builder 写法是 TS 最佳实践)
  extraReducers: (builder) => {
    builder.addCase(loginUser.fulfilled, (state, action) => {
      state.data = action.payload;
    });
  }
});

// Step 6
export const { logout } = userSlice.actions;
export default userSlice.reducer;
2. Store (store.ts)
typescript 复制代码
import { configureStore } from '@reduxjs/toolkit';
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
import userReducer from './userSlice';

// Step 7 & 8 (合并写法)
export const store = configureStore({
  reducer: {
    user: userReducer, // 这里自动 combineReducers
  },
});

// Step 9: 导出 TS 类型和 Hooks
export type RootState = ReturnType<typeof store.getState>;
export type AppDispatch = typeof store.dispatch;

export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
3. Component (Page.tsx)
typescript 复制代码
// Step 10
const dispatch = useAppDispatch();
// Step 11
const { data, loading } = useAppSelector(state => state.user);

// 触发操作
const handleLogin = () => {
  dispatch(loginUser({ username: 'admin' }));
};

// Step 12 (仅用于副作用)
useEffect(() => {
  if (data) {
    message.success('登录成功');
  }
}, [data]);
相关推荐
wordbaby10 分钟前
TanStack Router 实战:如何优雅地实现后台管理系统的“多页签” (TabList) 功能
前端·react.js
凌览22 分钟前
2026年1月编程语言排行榜|C#拿下年度语言,Python稳居第一
前端·后端·程序员
user861581857815426 分钟前
Element UI 表格 show-overflow-tooltip 长文本导致闪烁的根本原因与解法
前端
不会写前端的小丁30 分钟前
前端首屏渲染性能优化小技巧
前端
晴虹31 分钟前
lecen:一个更好的开源可视化系统搭建项目--组件和功能按钮的权限控制--全低代码|所见即所得|利用可视化设计器构建你的应用系统-做一
前端·后端·低代码
爱分享的鱼鱼33 分钟前
Pinia 深度解析:现代Vue应用状态管理最佳实践
前端·后端
花归去35 分钟前
echarts 柱状图包含右侧进度
开发语言·前端·javascript
多看书少吃饭1 小时前
Vite开发环境按需编译是怎么实现的
前端
ybb_ymm1 小时前
@Async修饰不生效
java·前端·数据库
Sapphire~1 小时前
Vue3-03 熟悉src文件夹及Vue文件格式
前端·javascript·vue.js