https://stackblitz.com/edit/react-ts-rkekhf?file=app/redux/asyncThunkFromFetch.ts
我们使用以下助手来创建 thunk:
import { createAsyncThunk } from '@reduxjs/toolkit';
import axios, { AxiosPromise, AxiosResponse } from 'axios';
import { store } from './store';
export const createAsyncThunkFromAPI = <ResponseSchema, RequestParams>(
typePrefix: string,
apiFunction: ApiFunction<RequestParams, ResponseSchema>
) => {
return createAsyncThunk<ResponseSchema, RequestParams>(
typePrefix,
async (args, thunkApi) => {
try {
const response = await apiFunction(args);
return response.data;
} catch (e) {
return thunkApi.rejectWithValue(e);
}
}
);
};
type ApiFunction<RequestParams, ResponseSchema> = (
axiosParams: RequestParams
) => AxiosPromise<ResponseSchema>;
export const getMobileOperatorsAPI = (): Promise<AxiosResponse<string[]>> => {
return axios.get('https://api.com');
};
export default createAsyncThunkFromAPI;
const sliceName = 'mobile-operators';
export const fetchMobileOperators = createAsyncThunkFromAPI(
`${sliceName}/fetchMobileOperators`,
getMobileOperatorsAPI
);
store.dispatch(fetchMobileOperators()); //Expected 1 arguments, but got 0.ts(2554)
store.dispatch(fetchMobileOperators({})); //Ouch!!!
我讨厌的一件事是,您不能将零参数传递给助手创建的 thunk 函数。然而,在我们的例子中,使用它而不是来自
createAsyncThunk
的裸
@redux/toolkit
仍然更方便
我试图为 payload creator 创建一个默认参数,但没有成功。但我真的不明白我在这里做什么。
如何调整
createAsyncThunkFromAPI
从API函数推断args
?
如何正确地实现相同的想法?
我错过了什么知识可以自己解决这个问题?
<ResponseSchema, RequestParams = never>
你离得很近,只是错过了一件小东西。您的 thunk 工厂将通过查看
ResponseSchema
的类型来推断泛型 RequestParams
和 apiFunction
的类型。这个特殊的 apiFunction
没有参数,因此 RequestParams
被推断为 unknown
。我们想确保它被推断为never
。因此我们添加一个默认值RequestParams = never
。这意味着当无法推断出args
时,不会接受任何RequestParams
。
export const createAsyncThunkFromAPI = <ResponseSchema, RequestParams = never>(
进行此更改后,所需的用法没有错误,而您的解决方案确实有错误。
store.dispatch(fetchMobileOperators()); // okay!
store.dispatch(fetchMobileOperators({})); // Expected 0 arguments, but got 1.(2554)
还有最后一件事要检查,以确保在有is 必需的参数时它仍然正常工作。我添加了一个额外的例子,果然它工作得很好。缺少参数时会出现错误,提供参数时不会出现错误。