在Redux结合TypeScript使用dispatch时出现类型错误
问题:Redux dispatch异步Action Creator时出现类型错误
错误提示:
Argument of type '(dispatch: Dispatch) => Promise' is not assignable to parameter of type 'AnyAction'.
对应的类型信息:
(alias) fetchUsers(): (dispatch: Dispatch<UserAction>) => Promise<void> import fetchUsers
相关文件代码
UserList.tsx
import React from "react"; import { useSelector } from "react-redux"; import { useTypedSelector } from "../hooks/useTypedSelector"; import { useDispatch } from "react-redux"; import { fetchUsers } from "../store/action-creator/user"; const UserList: React.FC = () => { const { users, error, loading } = useTypedSelector((state) => state.user); const dispatch = useDispatch(); React.useEffect(() => { dispatch(fetchUsers()) }, []) if (loading) { return <h1>Loading...</h1>; } if (error) { return <h1>{error}</h1>; } return ( <div> {users.map((user) => ( <div>{user.name}</div> ))} </div> ); }; export default UserList;
store/action-creator/user.ts
import { Dispatch } from "redux"; import { UserAction, UserActionTypes } from "../../types/user"; import axios from "axios"; export const fetchUsers = () => { return async (dispatch: Dispatch<UserAction>) => { try { dispatch({ type: UserActionTypes.FETCH_USERS }); const response = await axios.get( "https://jsonplaceholder.typicode.com/users" ); dispatch({ type: UserActionTypes.FETCH_USERS_SUCCESS, payload: response.data, }); } catch (e) { dispatch({ type: UserActionTypes.FETCH_USERS_ERROR, payload: "Error", }); } }; };
types/user.ts
export interface UserState { users: any[]; loading: boolean; error: null | string; } export enum UserActionTypes { FETCH_USERS = "FETCH_USERS", FETCH_USERS_SUCCESS = "FETCH_USERS_SUCCESS", FETCH_USERS_ERROR = "FETCH_USERS_ERROR", } interface FetchUserAction { type: UserActionTypes.FETCH_USERS; } interface FetchUserSuccessAction { type: UserActionTypes.FETCH_USERS_SUCCESS; payload: any[]; } interface FetchUserErrorAction { type: UserActionTypes.FETCH_USERS_ERROR; payload: string; } export type UserAction = | FetchUserAction | FetchUserSuccessAction | FetchUserErrorAction;
解决方案
1. 配置Redux Thunk中间件
你的fetchUsers是返回异步函数的Action Creator,必须依赖Redux Thunk中间件才能让dispatch识别这种类型的Action。
- 安装依赖:
npm install redux-thunk # 或 yarn add redux-thunk
- 在store配置中加入Thunk:
import { createStore, applyMiddleware } from 'redux'; import thunk from 'redux-thunk'; import rootReducer from './reducers'; export const store = createStore(rootReducer, applyMiddleware(thunk));
2. 修正Dispatch的类型定义
默认的useDispatch不知道Thunk的存在,需要给它指定支持Thunk的类型:
- 在store/index.ts中定义全局类型:
import { createStore, applyMiddleware } from 'redux'; import thunk, { ThunkDispatch } from 'redux-thunk'; import rootReducer from './reducers'; import type { UserAction } from './types/user'; export type RootState = { user: import('./types/user').UserState; }; // 定义支持Thunk的Dispatch类型 export type AppDispatch = ThunkDispatch<RootState, unknown, UserAction>; export const store = createStore(rootReducer, applyMiddleware(thunk));
- 自定义useAppDispatch Hook(可放在hooks/useTypedSelector.ts中):
import { useDispatch } from 'react-redux'; import type { AppDispatch } from '../store'; export const useAppDispatch = () => useDispatch<AppDispatch>();
- 在UserList.tsx中替换useDispatch为自定义的useAppDispatch:
// ... import { useTypedSelector, useAppDispatch } from "../hooks/useTypedSelector"; // ... const dispatch = useAppDispatch();
这样就能解决类型不匹配的问题,dispatch现在可以正确识别异步Action Creator。
内容的提问来源于stack exchange,提问作者user20743167
相关产品推荐
相关产品推荐

