Проблема с частью «CR» (обновление) CRUD в редукторах - PullRequest
1 голос
/ 13 октября 2019

Я работал над проектом 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' мне кажется немного отрывочным, я чувствую, что синтаксис неверен. Насколько я понимаю, для того, чтобы внести изменения в обновления. Выбранный элемент должен быть отсканирован из массива в соответствующий идентификатор. Как только идентификатор совпадает, изменения могут быть обновлены после отправки. И я не уверен, что смог бы понять, как добавить этот синтаксис.

Теперь компонент Редактировать форму с отправкой внутри 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;

Опять, я полагаюСинтаксис был реализован неправильно. Цель состоит в том, чтобы распределить в отдельные значения name и suffix на основе входного значения. У меня ничего не получалось, и в последнее время я боролся за меня. Как мне решить эту проблему? Какова была бы лучшая практика или правильный способ достижения "U" (обновления) детали внутри редуктора и диспетчера? Ваша помощь приветствуется и спасибо заранее.

Ответы [ 2 ]

1 голос
/ 15 октября 2019
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]

Если я не ошибаюсь, это должно вернуть исходное состояние вместе с обновленным конкретным элементом

Или вы можете сделать:

const newArr = state.map( obj => {
  if obj.id === action.id{
     obj['name'] = action.name;
     obj['suffix'] = action.suffix;
  }
  return obj
  });
return newArr;
0 голосов
/ 14 октября 2019

В случае обновления я бы порекомендовал сопоставить существующие элементы:

  • Если сопоставленный элемент имеет тот же идентификатор, что и обновленный, то замените его
  • Сохранитьв противном случае - существующий элемент

Вот код:

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

Коды и коробки здесь

...