在REDUX中存储数据的更好方法

mefy6pfw  于 2022-11-12  发布在  其他
关注(0)|答案(2)|浏览(210)

使用的语言:带有react / redux的javascript
我的项目:我有一个多步骤的表单。在每一步,当用户写一些东西或检查一些东西时,我用redux来存储状态。我有一个reducer,但我为表单的每一步创建一个action
我想做的事:我希望只有一个操作来逐步更新状态。
我现在在做什么(工作正常):
我包含每个步骤的页面

const Form = () => {

  return ( 
      <div className="page">
        <form>
          {
            {
              1: <StepOne />,
              2: <StepTwo />,
              3: <StepThree />,
            }[buttonDatas.pageNumber]
          }
        </form>
      </div>

  );
};

export default Form;

这里是步骤组件一个示例(stepOne)

import React, { useEffect, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { addName } from '../../../actions/form.action.js';
import { isEmpty } from '../../../middlewares/verification.js';

export const StepOne = () => {
  const dispatch = useDispatch();
  const usersList = useSelector((state) => state.userReducer);
  const [userName, setUserName] = useState();

  useEffect(() => {
    dispatch(addName(userName));
  }, [dispatch, userName]);

  return (
    <div>
      <label>Select the user name</label>
      <select
        name="name"
        onChange={(e) => {
          const userSelected = e.target.value;
          setUserName(userSelected);
        }}
        defaultValue={'default'}
      >
        <option value="default" hidden disabled>
          Select a user
        </option>
        {!isEmpty(usersList[0]) &&
          usersList.map((user) => {
            return (
              <option key={user.id}>
                {user.fullName}
              </option>
            );
          })}
      </select>
    </div>
  );
};

这里是我的减速器:

import {
  ADD_NAME,
  ADD_PHONE,
  ADD_ADDRESS,
} from '../actions/form.action';

const initialState = {
  userInfo: {
    name: '',
    phone : '',

  },
  address: ''
};

export default function formReducer(state = initialState, actions) {
  switch (actions.type) {

    case ADD_NAME:
      state = {
        ...state,
        userInfo: {
          name: actions.payload,
        },
      };
      return state;

    case ADD_PHONE:
      state = {
        ...state,
        userInfo: {
          phone: actions.payload,
        },
      };
      return state;

    case ADD_ADDRESS:
      state = {
        ...state,
        address: actions.payload,
        },
      };
      return state;

    default:
      return state;
  }
}

有没有更好的写法?

ifmq2ha2

ifmq2ha21#

您可以创建一个对象,使其包含整个多步骤表单向导布局中的所有必需属性值,并只维护一个操作以将数据保存在Redux存储中。而不是为同一表单的单个属性创建每个操作项。
在此我给你一个参考,这将有助于你组织你的代码根据您的要求。
我会建议你去通过下面两个链接:

  1. Redux Form multi-step wizard form
    1.是的。
kq0g1dla

kq0g1dla2#

有了nimish的指示,我已经使用redux工具包和react-hook-form,它工作得很好。
我改变了什么:用redux工具包创建一个切片文件(用于我的reducer和action)

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

const formSlice = createSlice({
  name: 'form',
  initialState: {
    userInfo: {
      name: '', 
      phone: ''
    },

    address: ''

  },
  reducers: {
    selectUserName: (state, action) => {
      state.userInfo.name = action.payload;
    },
    addUserPhone: (state, action) => {
      state.userInfo.phone = action.payload;
    },
    addAddress: (state, action) => {
      state.address = action.payload;
    },
  },
});

export const reducer = formSlice.reducer;

export const {
  selectUserName,
  addUserPhone,
  addAddress,
} = formSlice.actions;

在我userInfo组件中使用它

import React from 'react';
import { userName } from './userName';
import { userPhone } from './userPhone';
import { useDispatch, useSelector } from 'react-redux';

import {
  selectUserName,
  addUserPhone,
} from '../../../reducer/form.slice';
import { useForm } from 'react-hook-form';

export const UserInfo = () => {
  const dispatch = useDispatch();

  const state = useSelector((state) => state.reducer);

  const { register, handleSubmit } = useForm({
    defaultValues: {},
  });

  const onChange = (data) => {
    dispatch(selectUserName(data.name);
    dispatch(addUserPhone(data.phone));

  };

  return (
    <div>
      <h2 className="title"> Step One : Information User</h2>
      <form onChange={handleSubmit(onChange)} className="form">
        <userName register={register} />
        <userPhone register={register} />

      </form>

//to see your result 
      <pre>{JSON.stringify(state, null, 2)}</pre>
    </div>
  );
};

在子组件中

import React from 'react';
import { useSelector } from 'react-redux';
import { isEmpty } from '../../../middlewares/verification.js';

export const UserName = ({ register }) => {
  const userList = useSelector((state) => state.userReducer);

  return (
    <div className="form_group">
        <label>Select the user name</label>
      <select
        className="select"
        name="name"
        {...register('userName')}
        defaultValue={'default'}
      >
        <option value="default" hidden disabled>
          Select a user        
</option>
        {!isEmpty(userList[0]) &&
          userList.map((user) => {
            return (
              <option value={user.fullName} key={user.mail}>
                {user.fullName}
              </option>
            );
          })}
      </select>
    </div>
  );
};

谢谢你,谢谢。

相关问题