如何使用TypeScript简化Redux Thunk动作代码?
简化Redux Thunk + TypeScript代码的几个实用方案
看起来你已经在尝试精简Redux Thunk结合TypeScript的代码了,这里有几个能进一步简化的方向,从基础优化到官方推荐的工具方案都有:
1. 先优化基础类型与工具函数
消除any并复用动作类型
首先把模糊的any替换成具体类型,同时给动作类型创建别名减少重复书写:
// 给API_REQUEST动作创建类型别名,避免重复写ModalActionTypes["API_REQUEST"] type ApiRequestAction = ModalActionTypes["API_REQUEST"]; // 定义payload的具体类型(根据你的业务场景调整,比如结合IContactForm或其他接口) type ApiPayload = IContactForm | Record<string, unknown>; export function apiRequestDispatcher( status: string, payload?: ApiPayload ): ApiRequestAction { return { type: "API_REQUEST", status, // ES6属性简写,等价于status: status payload, // 同样简写 }; }
通用Thunk生成函数
如果有多个类似sendEmail的异步action,可以封装一个通用生成器,避免重复写Thunk的泛型参数:
// 提前定义全局Thunk类型,复用所有异步action type AppThunk<ReturnType = void> = ThunkAction< ReturnType, RootState, // 替换成你的根状态类型 unknown, ModalActionTypes >; // 通用API请求Thunk生成器 function createApiThunk<Payload>( apiCall: (payload: Payload) => Promise<any>, successStatus: string, errorStatus: string ) { return (payload: Payload): AppThunk<Promise<ApiRequestAction>> => async (dispatch) => { try { const response = await apiCall(payload); return dispatch(apiRequestDispatcher(successStatus, response)); } catch (error) { return dispatch(apiRequestDispatcher(errorStatus, error)); } }; } // 现在sendEmail可以极简定义 export const sendEmail = createApiThunk<IContactForm>( (details) => fetch("/api/email", { method: "POST", body: JSON.stringify(details) }), "EMAIL_SENT_SUCCESS", "EMAIL_SENT_ERROR" );
2. 推荐使用Redux Toolkit(官方最优解)
Redux Toolkit是官方推出的简化工具,内置Redux Thunk,对TypeScript支持非常友好,能彻底消除样板代码:
用createAsyncThunk替代手动Thunk
createAsyncThunk会自动生成pending/fulfilled/rejected三种状态的action,无需手动维护status:
import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; // 自动生成异步动作类型,无需手动定义字符串常量 export const sendEmail = createAsyncThunk( "modal/sendEmail", async (messageDetails: IContactForm) => { const response = await fetch("/api/email", { method: "POST", body: JSON.stringify(messageDetails), }); return response.json(); // 返回值会作为fulfilled动作的payload } ); // 用createSlice创建reducer,自动处理异步动作 const modalSlice = createSlice({ name: "modal", initialState: { status: "idle", data: null, error: null, }, reducers: {}, extraReducers: (builder) => { builder .addCase(sendEmail.pending, (state) => { state.status = "loading"; }) .addCase(sendEmail.fulfilled, (state, action) => { state.status = "success"; state.data = action.payload; }) .addCase(sendEmail.rejected, (state, action) => { state.status = "error"; state.error = action.error.message; }); }, }); export const modalReducer = modalSlice.reducer;
这套方案里,你不需要手动写apiRequestDispatcher,TypeScript会自动推断所有类型,代码量减少一半以上,还能避免拼写错误和类型不匹配问题。
3. 额外小技巧:用枚举管理动作类型
如果还在手动维护动作字符串,用枚举替代可以避免拼写错误:
enum ModalActionTypes { API_REQUEST = "API_REQUEST", // 其他动作类型 } // 在dispatcher里使用枚举: return { type: ModalActionTypes.API_REQUEST, status, payload, };
内容的提问来源于stack exchange,提问作者Andrew Font
相关产品推荐
相关产品推荐

