action.payload creactAsyncThunk 未定义
action.payload in creactAsyncThunk is undefined
我正在尝试使用带有 createAsyncThunk 的 axios 从 api 获取用户数据,并希望用户数据通过由createAsyncThunk.
如docs
中所述
if the promise resolved successfully, dispatch the fulfilled action with the promise value as action.payload.
但是 action.payload 在 fulfilled action creator 中未定义。
这是我的代码。
/// Create Async Thunk
export const fetchUserData = createAsyncThunk(
'user/fetchUserData',
(payload, { dispatch }) => {
axios
.get('/user')
.then(res => {
console.log(res.data);
//Used this as a work around for storing data
dispatch(setUser(res.data));
return res.data;
})
.catch(err => {
console.error(err);
return err;
});
}
);
/// On Fulfilled
const userSlice = createSlice({
...
extraReducers:{
...
[fetchUserData.fulfilled]: (state, action) => {
// Payload is undefined
state.data = action.payload
},
}
}
createAsyncThunk接受两个参数:
type
payloadCreator
其中 payloadCreator
是一个回调函数,它应该 return 一个 promise(包含一些异步逻辑的结果)或一个 值(同步)。
因此,您可以这样写:
export const fetchUserData = createAsyncThunk(
'user/fetchUserData',
(payload, { dispatch }) => {
return axios.get('/user'); // Return a promise
}
);
或
export const fetchUserData = createAsyncThunk(
'user/fetchUserData',
async (payload, { dispatch, rejectWithValue }) => {
try {
const response = await axios.get('/user')
return response // Return a value synchronously using Async-await
} catch (err) {
if (!err.response) {
throw err
}
return rejectWithValue(err.response)
}
}
);
@Ajeet Shah 回答的补充:
根据 to the documentation 被拒绝的承诺必须 return
- 一个Error-instance,如
new Error(<your message>)
,
- 普通值,例如描述性字符串,
- 或
RejectWithValue
return thunkAPI.rejectWithValue()
对于前两个选项,我还没有测试最后一个选项,有效载荷也将由 undefined
,但会给出一个包含您拒绝的消息的 error
参数。
看这个例子:
const loginAction = createAsyncThunk(
"user/login",
(payload, { getState }) => {
const { logged_in, currentRequestId, lastRequestId } = getState().login;
// Do not login if user is already logged in
if (logged_in) {
return Promise.reject(new Error(Cause.LoggedIn));
}
// Do not login if there is a pending login request
else if (lastRequestId != null && lastRequestId !== currentRequestId) {
return Promise.reject(new Error(Cause.Concurrent));
}
// May as well try logging in now...
return AccountManager.login(payload.email, payload.password);
}
);
我正在尝试使用带有 createAsyncThunk 的 axios 从 api 获取用户数据,并希望用户数据通过由createAsyncThunk.
如docs
中所述if the promise resolved successfully, dispatch the fulfilled action with the promise value as action.payload.
但是 action.payload 在 fulfilled action creator 中未定义。
这是我的代码。
/// Create Async Thunk
export const fetchUserData = createAsyncThunk(
'user/fetchUserData',
(payload, { dispatch }) => {
axios
.get('/user')
.then(res => {
console.log(res.data);
//Used this as a work around for storing data
dispatch(setUser(res.data));
return res.data;
})
.catch(err => {
console.error(err);
return err;
});
}
);
/// On Fulfilled
const userSlice = createSlice({
...
extraReducers:{
...
[fetchUserData.fulfilled]: (state, action) => {
// Payload is undefined
state.data = action.payload
},
}
}
createAsyncThunk接受两个参数:
type
payloadCreator
其中 payloadCreator
是一个回调函数,它应该 return 一个 promise(包含一些异步逻辑的结果)或一个 值(同步)。
因此,您可以这样写:
export const fetchUserData = createAsyncThunk(
'user/fetchUserData',
(payload, { dispatch }) => {
return axios.get('/user'); // Return a promise
}
);
或
export const fetchUserData = createAsyncThunk(
'user/fetchUserData',
async (payload, { dispatch, rejectWithValue }) => {
try {
const response = await axios.get('/user')
return response // Return a value synchronously using Async-await
} catch (err) {
if (!err.response) {
throw err
}
return rejectWithValue(err.response)
}
}
);
@Ajeet Shah 回答的补充:
根据 to the documentation 被拒绝的承诺必须 return
- 一个Error-instance,如
new Error(<your message>)
, - 普通值,例如描述性字符串,
- 或
RejectWithValue
returnthunkAPI.rejectWithValue()
对于前两个选项,我还没有测试最后一个选项,有效载荷也将由 undefined
,但会给出一个包含您拒绝的消息的 error
参数。
看这个例子:
const loginAction = createAsyncThunk(
"user/login",
(payload, { getState }) => {
const { logged_in, currentRequestId, lastRequestId } = getState().login;
// Do not login if user is already logged in
if (logged_in) {
return Promise.reject(new Error(Cause.LoggedIn));
}
// Do not login if there is a pending login request
else if (lastRequestId != null && lastRequestId !== currentRequestId) {
return Promise.reject(new Error(Cause.Concurrent));
}
// May as well try logging in now...
return AccountManager.login(payload.email, payload.password);
}
);