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]);
相关推荐
AI视觉网奇4 小时前
live2d 单图转模型 单图生成模型
java·前端·python
weixin_395448914 小时前
“一次性拼接 RM+FSD 做单次前向/反向”的方案
前端·javascript·推荐算法
一只爱吃糖的小羊4 小时前
深入 React 原理:Reconciliation
前端·javascript·react.js
哆啦A梦15884 小时前
商城后台管理系统 03 Vue项目-实现表格导出EXCEL表格
前端·vue.js·excel
程序员爱钓鱼4 小时前
BlackHole 2ch:macOS无杂音录屏与系统音频采集完整技术指南
前端·后端·设计模式
未来之窗软件服务4 小时前
幽冥大陆(五十二)V10酒店门锁SDK TypeScript——东方仙盟筑基期
前端·javascript·typescript·酒店门锁·仙盟创梦ide·东方仙盟·东方仙盟sdk
LYFlied4 小时前
【每日算法】LeetCode148. 排序链表
前端·数据结构·算法·leetcode·链表
m0_738120724 小时前
应急响应——知攻善防蓝队靶机Web-1溯源过程
前端·网络·python·安全·web安全·ssh