如何实现 Redux 切片器

How to implement Redux Slicer

您好,我正在开发一个注册应用程序,我正在使用 useState 挂钩来设置用户信息 这样就可以正常工作了

import React, { useState } from 'react';
import axios from 'axios';

const Registration = (props) => {

  const [user, setUser] = useState({
    email: '',
    password: '',
    password_confirmation: '',
  });


  const { email, password, password_confirmation } = user;

  const handlChange = (event) => {
    setUser({ ...user, [event.target.name]: event.target.value });

  };

  const handleSubmit = (event) => {
    axios
      .post(
        'http://localhost:3001/registrations',
        {
          user: {
            email: email,
            password: password,
            password_confirmation: 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;

现在的问题是我必须使用 Redux 来管理状态,所以创建了一个切片器 这是我的切片机, 我遇到的问题是我不知道如何将 redux 连接到我的注册组件, 例如,我假设表单中提供的信息是有效载荷,所以我将把它作为 action.payload 传递给我的减速器,我想我正在使用来自有效载荷的信息设置状态。

import { createSlice } from '@reduxjs/toolkit';

const initialState = {
  email: '',
  password: '',
  password_confirmation: '',
};

const registrationSlice = createSlice({
  name: 'registration',
  initialState,
  reducers: {
    setUsers: (state, action) => {
      const { email, password, password_confirmation } = action.payload;
      state = {
        email,
        password,
        password_confirmation,
      };
    },
  },
});

export const { setUsers } = registrationSlice.actions;

export default registrationSlice.reducer;

问题是我如何将它连接到我的组件,我在 Redux Toolkit 网站上读到我必须使用 dispatch 和 useSelector, 所以这就是我认为我在这里做的,但没有用, 我被困在这一点上,不知道如何解决。有人可以帮助我了解如何修复它并使其正常工作吗?

import React, { useState } from 'react';
import axios from 'axios';
import { useDispatch, useSelector } from 'react-redux';
import { setUsers } from '../../features/user/registrationSlice';

const Registration = (props) => {
  const dispatch = useDispatch();

  const user = useSelector((state) => state.user);
  // const { email, password, password_confirmation } = user;

  const handlChange = (event) => {
    dispatch(setUsers({ [event.target.name]: event.target.value }));
  };

  const handleSubmit = (event) => {
    axios
      .post(
        'http://localhost:3001/registrations',
        {
          user: {
            email: email,
            password: password,
            password_confirmation: 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;

问题

这里的问题是你的 reducer 案例期望“全套”状态属性同时更新,但 UI 正在为每个子状态单独调度操作。

解决方案

我建议更新 reducer,或者更确切地说,添加一个新的 reducer 来处理设置各个状态属性。这样就可以根据需要设置整个状态。

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

并调度新的 setUserProperty 操作。

const handlChange = (event) => {
  dispatch(setUserProperty({
    name: event.target.name,
    value: event.target.value,
  }));
};

由于您使用的是 Redux-toolkit,因此您可能希望最终考虑通过 createAsyncThunk 将所有异步 axios POST 请求逻辑移动到一个 thunk 中。 thunk 将有权访问存储以获取用户值并进行异步调用。这将允许您进一步将 Registration 组件与 auth/registration 逻辑和您的 redux 状态分离。