Consider cases where we don't need to provide an argument to the async thunk.
Currently, you have to provide it, at least with _.
What about having payloadCreator with optional thunkArg?
Not sure what you're asking here. Can you provide a concrete example? Are you asking about a plain JS restriction, or something in the TS types?
Not sure what you're asking here. Can you provide a concrete example? Are you asking about a plain JS restriction, or something in the TS types?
Hey there.
something in the TS types
arg parameter is not optional here, though it's typed as void by default.
Is it possible to have it optional?
You need to know if github.com is up or down, so it will be an async thunk that returns boolean.
So you're going to create it:
export const checkGithub = createAsyncThunk('@check/GITHUB', async thunkAPI => {
let fetched: boolean
/* fetching */
return fetched
}
But this won't work, as thunkAPI will be typed as void, so you have to change first line to next:
export const checkGithub = createAsyncThunk('@check/GITHUB', async (_, thunkAPI) => {
Now it will work
Still not sure what you're getting at here.
thunkAPI will always be passed in as the second argument to the payload creator, so you can't just leave out the first argument when you declare your function. If you don't need thunkAPI at all, you ought to be able to do async () => {}, but if you need thunkAPI, then you _have_ to declare _something_ for the first parameter because they're both positional.
Still not sure what you're getting at here.
thunkAPIwill always be passed in as the second argument to the payload creator, so you can't just leave out the first argument when you declare your function. If you don't needthunkAPIat all, you ought to be able to doasync () => {}, but if you needthunkAPI, then you _have_ to declare _something_ for the first parameter because they're both positional.
No no, I'm talking about the cases when you need thunkAPI but don't need the first payload argument, so your dispatched async action doesn't have the payload.
That's my point exactly. We pass thunkAPI positionally, as the second arg. Therefore, you _must_ declare a first arg in front of it in your function. That's how the API is designed, period.
(Also, the first arg isn't a "payload". Your callback returns what becomes the action.payload for the dispatched action. The first arg is "the arguments to the thunk".)
(Also, the first arg isn't a "payload". Your callback returns what becomes the action.payload for the dispatched action. The first arg is "the arguments to the thunk".)
Yeah sure.
That's how the API is designed, period.
However, it's still possible to overload AsyncThunkPayloadCreator to not have the first thunk argument, so you don't have in some cases useless argument.
export type AsyncThunkPayloadCreator<
Returned,
ThunkApiConfig extends AsyncThunkConfig = {}
> = (
thunkAPI: GetThunkAPI<ThunkApiConfig>
) => AsyncThunkPayloadCreatorReturnValue<Returned, ThunkApiConfig>
Yes, in TypeScript this would be possible on the declaration side, but it is not possible to detect on runtime, so we could not possibly implement it.
Given a callback that takes one argument (we could actually detect that by Function.protoype.length, I was wrong about that in an earlier edit of this comment), is is not possible for us to distinguish that one argument is meant to be args or thunkApi. So what should we pass in?
This is just not possible in JavaScript.
And even if it was, it probably would be highly confusing for many users. No interface should be that dynamic.
Given a callback that takes one argument (we could actually detect that by Function.protoype.length, I was wrong about that in an earlier edit of this comment), is is not possible for us to distinguish that one argument is meant to be
argsorthunkApi. So what should we pass in?
Of course, we have to choose if there's one argument either should we pass arg or thunkAPI, and I think that it's smart to always pass thunkAPI.
Just think like in how many cases you need thunkAPI (you always need it if you want to reject correctly) and in how many cases you need arg (which you may not need if your thunk doesn't consume any argument.
Maybe it's just me and I'm thinking wrong.
However, creating async thunk as action = createAsyncThunk(_, () => { /* my CB */ }) succeed my needs, and I can call async thunk with no arguments like await action.
But I still personally think that you almost always have to use thunkAPI and if the function has only one argument, it has to be treated as thunkAPI. What do you think about it?
About 70-80% of our users will probably never use thunkApi.
Oooh, now I got it.
From docs:
If there is an error, it should either return a rejected promise containing an Error instance or a plain value such as a descriptive error message or otherwise a resolved promise with a RejectWithValue argument as returned by the thunkApi.rejectWithValue function.
I thought that the only right way to reject form thunk is with thunkAPI.rejectWithValue.
Thanks for clearing that up!
BTW, found some typos: non-code examples have thunkApi when code examples use thunkAPI.
Most helpful comment
Of course, we have to choose if there's one argument either should we pass
argorthunkAPI, and I think that it's smart to always passthunkAPI.Just think like in how many cases you need
thunkAPI(you always need it if you want to reject correctly) and in how many cases you needarg(which you may not need if your thunk doesn't consume any argument.Maybe it's just me and I'm thinking wrong.
However, creating async thunk as
action = createAsyncThunk(_, () => { /* my CB */ })succeed my needs, and I can call async thunk with no arguments likeawait action.But I still personally think that you almost always have to use
thunkAPIand if the function has only one argument, it has to be treated asthunkAPI. What do you think about it?