我正在尝试通过 createAsyncThunk 将异步 Axios POST 请求逻辑从我的注册组件移动到一个 thunk。
这是我的注册组件
import React from 'react';
import axios from 'axios';
import { useDispatch, useSelector } from 'react-redux';
import { setUserProperty } from '../../features/user/registrationSlice';
const Registration = (props) => {
const dispatch = useDispatch();
const user = useSelector((state) => state);
const { email, password, password_confirmation } = user;
const handlChange = (event) => {
dispatch(
setUserProperty({
name: event.target.name,
value: event.target.value,
}),
);
};
const handleSubmit = (event) => {
axios
.post(
'http://localhost:3001/registrations',
{
user: {
email,
password,
password_confirmation,
},
},
{ withCredentials: true },
)
.then((response) => {
if (response.data.status === 'created') {
props.handleSuccessfulAuth(response.data);
}
})
.catch((error) => {
console.log('registration error', error);
});
event.preventDefault();
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="email"
name="email"
placeholder="Email"
value={email}
onChange={handlChange}
required
/>
<input
type="password"
name="password"
placeholder="Password"
value={password}
onChange={handlChange}
required
/>
<input
type="password"
name="password_confirmation"
placeholder="Confirm Password"
value={password_confirmation}
onChange={handlChange}
required
/>
<button tupe="submit">Register</button>
</form>
</div>
);
};
export default Registration;
这是我使用 createAsyncThunk
中的文档得出的结论import axios from 'axios';
import { createSlice, createAsyncThunk } from '@reduxjs/toolkit';
export const getUsers = createAsyncThunk('registration/getUsers', async () => {
return axios
.post(
'http://localhost:3001/registrations',
{
user: {
email,
password,
password_confirmation,
},
},
{ withCredentials: true },
)
.then((response) => {
if (response.data.status === 'created') {
return response.data;
}
});
});
const initialState = {
user: {
email: '',
password: '',
password_confirmation: '',
},
loading: false,
error: null,
};
const registrationSlice = createSlice({
name: 'registration',
initialState,
reducers: {
setUsers: (state, action) => {
const { email, password, password_confirmation } = action.payload;
state = {
email,
password,
password_confirmation,
};
},
setUserProperty: (state, action) => {
const { name, value } = action.payload;
state[name] = value;
},
extrareducers: {
[getUsers.pending]: (state, action) => {
state.loading = true;
},
[getUsers.fulfilled]: (state, action) => {
state.user = action.payload;
state.loading = false;
},
[getUsers.rejected]: (state, action) => {
state.error = action.error.message;
state.loading = false;
},
},
},
});
export const { setUsers, setUserProperty, getUsers } =
registrationSlice.actions;
export default registrationSlice.reducer;
但是每当我运行它时,我都会不断收到错误消息,例如,当我在 getUsers 函数中进行调用时,我收到未定义电子邮件、密码和 password_confirmation 的错误,我明白为什么并且是因为我是没有像我在注册组件中提供的那样从用户那里提取信息,但我不知道如何修复它或使其工作。我想了解如何解决问题。
答案 0 :(得分:1)
在负载创建器中,您应该访问 thunkAPI
到 getState
方法以访问存储的 registration.user
状态。
const {
registration: {
user: {
email,
password,
password_confirmation
},
},
} = getState();
export const getUsers = createAsyncThunk(
'registration/getUsers',
async (arg, { getState }) => {
const {
registration: {
user: {
email,
password,
password_confirmation
},
},
} = getState();
return axios
.post(
'http://localhost:3001/registrations',
{
user: {
email,
password,
password_confirmation,
},
},
{ withCredentials: true },
)
.then((response) => {
if (response.data.status === 'created') {
return response.data;
}
});
});
extraReducers
应与 reducers
键处于同一级别。
const registrationSlice = createSlice({
name: 'registration',
initialState,
reducers: {
setUsers: (state, action) => {
const { email, password, password_confirmation } = action.payload;
state.user = {
email,
password,
password_confirmation,
};
},
setUserProperty: (state, action) => {
const { name, value } = action.payload;
state.user[name] = value;
},
},
extraReducers: {
[getUsers.pending]: (state, action) => {
state.loading = true;
},
[getUsers.fulfilled]: (state, action) => {
state.user = action.payload;
state.loading = false;
},
[getUsers.rejected]: (state, action) => {
state.error = action.error.message;
state.loading = false;
},
},
});