“AsyncThunkAction<any, void, {}>”类型的参数不可分配给“AnyAction”类型的参数

问题描述 投票:0回答:13

store.ts

export const store = configureStore({
    reducer: {
        auth: authReducer
    },
    middleware: [],
});

export type AppDispatch = typeof store.dispatch;
export type RootState = ReturnType<typeof store.getState>;

hooks.ts

export const useAppDispatch = () => useDispatch<AppDispatch>();
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;

authSlice.ts(导致问题的函数)

export const fetchUser = createAsyncThunk(
    'users/fetchByTok',
    async () => {
        const res = await getUser();
        return res.data;
    }
)

Auth.ts

const Auth = ({ component, isLogged }: {component: any, isLogged: boolean}) => {
    const dispatch = useAppDispatch();
    
    useEffect(() => {
        dispatch(fetchUser()) // <----------- ERROR
    }, []);

    return isLogged ? component : <Navigate to='/sign-in' replace={true} />;
}

export default Auth;

我有一个createAsyncThunk函数来获取用户,但我实际上无法将它放入dispatch()中...

  • “AsyncThunkAction”类型的参数不可分配给“AnyAction”类型的参数。
  • “AsyncThunkAction”类型中缺少属性“type”,但“AnyAction”类型中需要属性“type”。ts(2345)
第一次使用这个,所以最好有一个很好的解释:)。

reactjs react-redux redux-thunk redux-toolkit
13个回答
103
投票
我遇到了同样的问题,对我来说,只需将

AppDispatch

 添加到 
useDispatch
 钩子类型即可解决;

const dispatch = useDispatch<AppDispatch>(); useEffect(() => { dispatch(getUsers()); }, []);
getUsers() 是我的 

createAsyncThunk

 函数


17
投票
其余的答案建议通过推理更新

store.dispatch

的类型,
我也更喜欢。

在这里,如果由于某种原因您无法通过推理解决它,我想建议使用显式类型定义的替代方案(这可能发生在较大的项目等中)

所以这里的想法是使用支持 thunk 操作的更新的调度类型来显式定义 Redux 存储的类型。

使用显式类型声明的解决方案

// your redux store config file. import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux"; import reducers from "./path/to/reducers"; // ... your code // 1. Get the root state's type from reducers export type RootState = ReturnType<typeof reducers>; // 2. Create a type for thunk dispatch export type AppThunkDispatch = ThunkDispatch<RootState, any, AnyAction>; // 3. Create a type for store using RootState and Thunk enabled dispatch export type AppStore = Omit<Store<RootState, AnyAction>, "dispatch"> & { dispatch: AppThunkDispatch; }; //4. create the store with your custom AppStore export const store: AppStore = configureStore(); // you can also create some redux hooks using the above explicit types export const useAppDispatch = () => useDispatch<AppThunkDispatch>(); export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
使用上述方法,您还可以使用 

store.dispatch

 来分派异步 thunk 操作(在编写测试时可能会有所帮助)

或使用

useAppDispatch

 挂钩

或使用

connect

 中的旧式 
react-redux
 消费者功能。

它会在所有情况下为您提供正确的类型。

我个人大多数时候更喜欢推理类型声明,但有时由于外部或内部原因我们别无选择。

希望这个答案对您有所帮助。谢谢你:)


14
投票
对我来说,解决方案是更严格地遵循 RTK 文档示例。

所以使用

concat

...

const store = configureStore({ middleware: (getDefaultMiddleware) => getDefaultMiddleware().concat(FooApi.middleware, apiErrorMiddleware), ...rest_of_the_config, });
...而不是分散数组...

const store = configureStore({ middleware: (getDefaultMiddleware) => [...getDefaultMiddleware(), FooApi.middleware, apiErrorMiddleware], ...rest_of_the_config, });
    

12
投票
这对我有用

import {ThunkDispatch} from "@reduxjs/toolkit"; const dispatch = useDispatch<ThunkDispatch<any, any, any>>();
    

10
投票
对我来说最简单的解决方案是替换:

const dispatch = useDispatch();
与:

const dispatch = useDispatch<any>();
    

6
投票

编辑!

由于评论中提到redux工具包实际上默认添加了Thunk,因此Phry的答案更准确。我无法删除已接受的答案,因此此编辑就足够了。

我提供的答案将删除自动添加的其他中间件!

问题在于您实际上缺少存储配置内的 thunk 中间件。只需添加

thunkMiddleware

 的导入并将其添加到配置中的 
middleware
 数组中即可。由于未添加中间件,调度不会接受 Thunk Action,因为 redux 不支持开箱即用。

import thunkMiddleware from 'redux-thunk'; export const store = configureStore({ reducer: { auth: authReducer }, middleware: [thunkMiddleware], });
    

3
投票
从“redux-thunk/extend-redux”导入*作为reduxThunk;

尝试在 redux 存储配置文件或根文件 - app.js/index.js 中添加此导入语句,或者如果是下一个 js - _app.js 在页面目录中。

例如:store.js

import { configureStore } from "@reduxjs/toolkit"; import rootReducer from "./reducers"; import * as reduxThunk from "redux-thunk/extend-redux"; export const store = configureStore({ reducer: rootReducer, }); export default store;
    

1
投票
如果您的 4.0.5 和 4.1.x 版本中都有

redux

,那么会出现这样的常见 TS 问题。
对于很多人来说,卸载并重新安装
node_modules

react-redux

似乎可以解决问题。
否则,您的捆绑程序可能会帮助您找到问题的根源(
@types/react-redux

npm ls redux

,如果您使用的是这两者之一)。

您已在商店配置中将默认中间件替换为空数组。所以,你的应用程序没有 redux-thunk。

1
投票
你可以这样做:

yarn why redux

然后将此数组添加到配置对象中。
    

如果你没有任何中间件,不要将其添加为空数组,只需将其删除即可。

1
投票
如果您有一些中间件,则必须使用

const middleware = [ ...getDefaultMiddleware(), /* custom middlewares */ ];

方法将其与默认中间件合并

concat

切勿使用扩展运算符来合并中间件。 Spread 运算符不会保留类型,但
middleware: getDefaultMiddleware => getDefaultMiddleware().concat(yourMiddleware)
方法会保留。


我想出了我的情况,如果你使用

1
投票
中的

configureStore

 并想使用中间件,那么你不能像这样写一些想法:
'@reduxjs/toolkit'

而不是这个,你应该使用这个:
export const store = configureStore({
    reducer: {
        r1: r1Reducer,
    },
    devTools: true,
    middleware: [
       reduxLogger
    ],
});

或使用
@andrewnosov

answer

对我来说这是打字稿的问题,根据文档添加

0
投票
类型解决了这个问题。更多信息:

https://redux-toolkit.js.org/api/createAsyncThunk

尤其是最后部分。

这是

0
投票
文档建议的最终对我有用的内容:

createAsyncThunk()

store.ts

export type AppDispatch = typeof store.dispatch

hooks.ts

export const useAppDispatch: () => AppDispatch = useDispatch

yourComponent.tsx


© www.soinside.com 2019 - 2024. All rights reserved.