减速器中 CRUD 的 "U"(更新)部分出现问题

Issue with the "U" (update) part of CRUD in reducers

我一直在研究无 redux 的 CRUD 项目。结合使用 contextAPI/hooks 创建类别列表。 "CR and D"(创建、读取和删除)部分我已经成功了,但是在 "U"(更新)部分苦苦挣扎,在提交更新更改后我无法让它工作。

从我如何处理减速器组件开始...

reducer.js

import uniqid from 'uniqid';

export const categoryReducer = (state, action) => {
    switch (action.type) {
        case 'ADD_CATEGORY':
            return [
                ...state,
                {
                    id: uniqid(),
                    name: action.name,
                    suffix: action.suffix
                }
            ];

       //**MY ISSUES**
        case 'UPDATE_CATEGORY':
            return (
                state.findIndex(item => item.id === action.id),
                state.slice(0, action.id, action.name, action.suffix)
            );
        case 'REMOVE_CATEGORY':
            return state.filter(item => item.id !== action.id);
        default:
            return state;
    }
};

'ADD_CATEGORY''DELETE_CATEGORY' 可以忽略,因为我没有问题。 'UPDATE_CATEGORY' 对我来说有点粗略,我觉得语法不正确。据我了解,为了进行更新更改。需要将所选项目从数组中扫描到匹配的 ID 中。一旦 id 匹配,更改可以在提交后更新。而且我不确定我能否弄清楚如何添加该语法。

现在 handleSubmit 函数中带有调度的编辑表单组件...

EditCategoryForm.js

import React, { useState, useContext, useEffect } from 'react';

//context
import { CategoryContext } from '../contexts/categoryContext';

function EditCategoryForm() {
    const { dispatch } = useContext( CategoryContext);

/*Not not get this to work */
    const handleSubmit = (e, name, suffix) => {
        e.preventDefault();
        dispatch({
            type: 'EDIT_CATEGORY',
            name,
            suffix
        });
     };

    const handleChange = e => {
        const { name, value } = e.target;
        setInputValue(prevState => ({ ...prevState, [name]: value }));
    };

    return (
        <form onSubmit={handleSubmit}>
            <h1>Edit</h1>
            <input
                type="text"
                name="name"
                value={inputValue.name}
                onChange={handleChange}
            />
            <input
                type="text"
                name="suffix"
                value={inputValue.suffix}
                onChange={handleChange}
            />
            <button>Submit Change</button>
            <button onClick={() => setEditing(false)}>Cancel</button>
        </form>
    );
}

export default EditCategoryForm;

同样,我认为语法执行有误。目标是根据输入值分派 namesuffix 的单独值。我没有取得任何成功,最近它一直在为我而苦苦挣扎。我该如何解决这个问题?在 reducer 和 dispatcher 中实现 "U" (update) 部分的最佳实践或正确方法是什么?感谢您的帮助,并提前致谢。

在更新案例中,我建议通过您现有的项目进行映射:

  • 如果映射的项目与更新的项目具有相同的 id,则替换它
  • 否则保留现有项目

代码如下:

case 'UPDATE_CATEGORY':
  return state.map(item => {
    if (item.id === action.id) {
      return {...item, name: action.name, suffix: action.suffix };
    }
    return item;
  });

缺少初始化状态的部分。我假设它是这样的:

const [inputValue, setInputValue] = useState({name: '',  suffix: ''})

handleSubmit函数接收单个参数(事件),您需要使用来自您的状态的值:

// remove the extra parameters
const handleSubmit = (e /*, name, suffix */) => {
    e.preventDefault();
    dispatch({
        type: 'UPDATE_CATEGORY',
        id: inputValue.id,
        name: inputValue.name,
        suffix: inputValue.suffix,
    });
};

Codesandbox here

case 'UPDATE_CATEGORY':
   let update_obj = state.find( obj => obj.id === action.id);
   update_obj['name'] = action.name;
   update_obj['suffix'] = action.suffix;

   return [...state, update_obj]

如果我没记错的话,这应该是 return 原始状态,以及更新后的特定元素

或者你可以这样做:

const newArr = state.map( obj => {
  if obj.id === action.id{
     obj['name'] = action.name;
     obj['suffix'] = action.suffix;
  }
  return obj
  });
return newArr;