如何实现 createAsyncThunk [英] how to implement createAsyncThunk

查看:77
本文介绍了如何实现 createAsyncThunk的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试通过 createAsyncThunk 将异步 Axios POST 请求逻辑从我的注册组件移动到一个 thunk.

这是我的注册组件

从'react'导入React;从 'axios' 导入 axios;import { useDispatch, useSelector } from 'react-redux';import { setUserProperty } from '../../features/user/registrationSlice';const 注册 = (props) =>{const dispatch = useDispatch();const user = useSelector((state) => state);const { 电子邮件,密码,password_confirmation } = 用户;consthandlChange = (事件) =>{派遣(设置用户属性({名称:event.target.name,值:事件.目标.值,}),);};const handleSubmit = (事件) =>{公理.邮政('http://localhost:3001/registrations',{用户:{电子邮件,密码,确认密码,},},{ withCredentials: true },).then((响应) => {if (response.data.status === '创建') {props.handleSuccessfulAuth(response.data);}}).catch((错误) => {console.log('注册错误', 错误);});event.preventDefault();};返回 (<div><form onSubmit={handleSubmit}><输入类型=电子邮件"名称=电子邮件"占位符=电子邮件"值={电子邮件}onChange={handlChange}必需的/><输入类型=密码"名称=密码"占位符=密码"值={密码}onChange={handlChange}必需的/><输入类型=密码"name="password_confirmation";placeholder="确认密码";值={password_confirmation}onChange={handlChange}必需的/><button tupe="submit">注册</button></表单>

);};导出默认注册;

这是我使用 createAsyncThunk 中的文档得出的结论

从'axios'导入axios;导入 { createSlice, createAsyncThunk } from '@reduxjs/toolkit';export const getUsers = createAsyncThunk('registration/getUsers', async() => {返回 axios.邮政('http://localhost:3001/registrations',{用户:{电子邮件,密码,确认密码,},},{ withCredentials: true },).then((响应) => {if (response.data.status === '创建') {返回 response.data;}});});常量初始状态 = {用户:{电子邮件: '',密码: '',确认密码: '',},加载:假,错误:空,};const registrationSlice = createSlice({name: '注册',初始状态,减速器:{setUsers:(状态,动作)=>{const { 电子邮件,密码,password_confirmation } = action.payload;状态 = {电子邮件,密码,确认密码,};},setUserProperty: (state, action) =>{const { name, value } = action.payload;状态[名称] = 值;},额外减速器:{[getUsers.pending]:(状态,动作)=>{state.loading = true;},[getUsers.fulfilled]:(状态,动作)=>{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.reducer;

但是每当我运行它时,我都会不断收到错误消息,例如,当我在 getUsers 函数中进行调用时,我收到未定义电子邮件、密码和 password_confirmation 的错误,我明白为什么并且是因为我是没有像我在注册组件中提供的那样从用户那里提取信息,但我不知道如何修复它或使其工作.我想了解如何解决问题.

解决方案

在负载创建器中,您应该访问 thunkAPIgetState 方法以访问存储的 registration.user 状态.

const {登记: {用户:{电子邮件,密码,确认密码},},} = getState();

export const getUsers = createAsyncThunk('注册/获取用户',异步 (arg, { getState }) =>{常量{登记: {用户:{电子邮件,密码,确认密码},},} = getState();返回 axios.邮政('http://localhost:3001/registrations',{用户:{电子邮件,密码,确认密码,},},{ withCredentials: true },).then((响应) => {if (response.data.status === '创建') {返回 response.data;}});});

extraReducers 应该与 reducers 键处于同一级别.

const registrationSlice = createSlice({name: '注册',初始状态,减速器:{setUsers:(状态,动作)=>{const { 电子邮件,密码,password_confirmation } = action.payload;状态.用户 = {电子邮件,密码,确认密码,};},setUserProperty: (state, action) =>{const { name, value } = action.payload;state.user[name] = value;},},额外的减速器:{[getUsers.pending]:(状态,动作)=>{state.loading = true;},[getUsers.fulfilled]:(状态,动作)=>{state.user = action.payload;state.loading = false;},[getUsers.rejected]: (state, action) =>{state.error = action.error.message;state.loading = false;},},});

I am trying to move the asynchronous Axios POST request logic from my registration component into a thunk via the createAsyncThunk.

Here is my registration component

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;

and here is what I was able to come up using documentation from the 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;

but anytime I run it I keep on getting errors, for example, I get the error that the email, password, and password_confirmation is not defined when I make the call inside the getUsers function, I understand why and is because I am not pulling the information from the user like I have I available in my registration component, but I have no clue as to how to fix it or make it work. I want to understand how to fix the problem.

解决方案

In the payload creator you should access the thunkAPI to the getState method to access the stored registration.user state.

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;
        }
      });
});

The extraReducers should be at the same level as the reducers key.

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;
    },
  },
});

这篇关于如何实现 createAsyncThunk的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆