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]);
相关推荐
漂流瓶jz2 小时前
Webpack如何实现万物皆可import?loader的使用/配置/手写实践
前端·javascript·webpack
ZC跨境爬虫2 小时前
跟着 MDN 学CSS day_41:显式轨道、隐式网格与区域命名放置
前端·javascript·css·ui·交互
修己xj3 小时前
告别手动存图!这款叫 Fatkun 的浏览器插件,简直是素材收集神器
前端
袋鼠云数栈4 小时前
从前端到基础设施,ACOS 如何打通企业全链路可观测
运维·前端·人工智能·数据治理·数据智能
AskHarries4 小时前
系统提示词、开发者指令和用户输入的优先级
java·前端·数据库
Moment4 小时前
长上下文会最终杀死 Rag 吗?
前端·javascript·后端
qcx235 小时前
【系统学AI】25 论文导读 ①:两篇改变 AI 的开山之作——Attention Is All You Need & ReAct
前端·人工智能·react.js·transformer
kyriewen6 小时前
大文件上传最全指南:分片、断点续传、秒传,一篇就够了
前端·javascript·面试
郑洁文6 小时前
基于Python的Web命令执行漏洞自动化检测系统
前端·python·网络安全·自动化
新酱爱学习6 小时前
手搓 10 个 Skill 后,我把重复劳动收敛成了一套零依赖 CLI 工具
前端·javascript·人工智能