Next.js中使用Redux Toolkit Async Thunk遇类型错误求助
问题:Next.js + Redux Toolkit AsyncThunk 类型错误
我正在用Next.js和Redux Toolkit创建async thunk,从数据库取数据存入全局状态,减少请求并实现全应用共享。计划在首页dispatch这个动作提前获取数据(首页按钮需要访问数据)。
但在组件中调用dispatch(fetchDisplates());时,出现TypeScript错误:
Argument of type 'AsyncThunkAction<any, void, AsyncThunkConfig>' is not assignable to parameter of type 'AnyAction'.ts(2345)
我的相关代码:
Displate Slice 代码:
"use client"; import { createAsyncThunk, createSlice } from "@reduxjs/toolkit"; import { IDisplateInfo } from "@/app/types/types"; import axios from "axios"; import type { PayloadAction } from "@reduxjs/toolkit"; export const fetchDisplates = createAsyncThunk("getDisplates", async () => { const response = await axios.get("api/displates"); if (response.status === 200) { const displates = response.data; return displates; } }); export interface DisplateState { displates: IDisplateInfo[]; currentDisplate: IDisplateInfo; favoriteDisplates: IDisplateInfo[]; displateCategories: IDisplateInfo[]; } const initialState: DisplateState = { displates: [], currentDisplate: { img: null, title: null, category: null, id: null, }, favoriteDisplates: [], displateCategories: [], }; export const displateSlice = createSlice({ name: "displate", initialState, reducers: { setDisplates: (state, action: PayloadAction<IDisplateInfo[]>) => { state.displates = action.payload; }, setCurrentDisplate: (state, action: PayloadAction<IDisplateInfo>) => { state.currentDisplate = action.payload; }, setFavoriteDisplates: (state, action: PayloadAction<IDisplateInfo[]>) => { state.favoriteDisplates = action.payload; }, setDisplateCategories: (state, action: PayloadAction<IDisplateInfo[]>) => { state.displateCategories = action.payload; }, }, extraReducers: (builder) => { builder.addCase(fetchDisplates.fulfilled, (state, action) => { state.displates = action.payload; }); }, }); export const { setCurrentDisplate, setDisplates, setFavoriteDisplates, setDisplateCategories, } = displateSlice.actions; export default displateSlice.reducer;
API GET 函数:
export const GET = cache(async (request: Request) => { const currentUser = getCurrentUser(); console.log(request); const displates = await prisma.displateInfo.findMany(); return NextResponse.json(displates); });
Store 代码:
"use client"; import { configureStore } from "@reduxjs/toolkit"; import userReducer from "../redux/features/user/userSlice"; import displateReducer from "./features/displate/displateSlice"; export const store = configureStore({ reducer: { user: userReducer, displate: displateReducer, }, }); export type RootState = ReturnType<typeof store.getState>; export type AppDispatch = typeof store.dispatch;
解决方案:
这个错误是因为没有正确给useDispatch指定类型,默认的useDispatch只接受AnyAction类型,而AsyncThunk返回的是AsyncThunkAction,类型不匹配。
步骤1:创建自定义的useDispatch钩子
在你的store文件(或单独的hooks文件)中,导出一个类型化的useAppDispatch钩子:
// store.ts文件中添加 import { useDispatch } from "react-redux"; export const useAppDispatch = () => useDispatch<AppDispatch>();
步骤2:在组件中使用自定义的useAppDispatch
替换原来的useDispatch,用useAppDispatch来获取dispatch函数:
"use client"; import { useEffect } from "react"; import { useAppDispatch } from "@/app/store"; // 路径根据项目调整 import { fetchDisplates } from "@/app/redux/features/displate/displateSlice"; export default function Home() { const dispatch = useAppDispatch(); useEffect(() => { dispatch(fetchDisplates()); }, [dispatch]); return ( {/* 组件内容 */} ); }
可选:给AsyncThunk添加更精确的类型
为了让类型更严谨,可以给fetchDisplates指定返回值和参数类型:
export const fetchDisplates = createAsyncThunk<IDisplateInfo[], void>( "getDisplates", async () => { const response = await axios.get<IDisplateInfo[]>("api/displates"); if (response.status === 200) { return response.data; } // 添加错误处理,避免无返回值的情况 throw new Error("Failed to fetch displates"); } );
这样不仅解决了类型错误,还让代码的类型提示更准确。
内容的提问来源于stack exchange,提问作者Mathew
相关产品推荐
相关产品推荐

