如何实现 createAsyncThunk

时间:2021-06-30 23:06:38

标签: reactjs redux react-redux redux-toolkit

我正在尝试通过 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 的错误,我明白为什么并且是因为我是没有像我在注册组件中提供的那样从用户那里提取信息,但我不知道如何修复它或使其工作。我想了解如何解决问题。

1 个答案:

答案 0 :(得分:1)

在负载创建器中,您应该访问 thunkAPIgetState 方法以访问存储的 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;
    },
  },
});