Лучший способ редактировать свойства вложенных объектов с отдельными компонентами реагирования? - PullRequest
1 голос
/ 10 октября 2019

Я пытаюсь создать форму React / редактируемую таблицу, которая позволяет пользователю редактировать объект со следующей структурой:

{ID, name, year, number, categories: [ {ID, name, options: [ {ID, name} ] } ] }

Я пытался найти эффективный и чистый способ отображения данныхэтой формы, разрешить редактирование и отслеживать отредактированные данные в некотором родительском компоненте. Редактировать свойства уровня поверхности было довольно легко (и я считаю чистым). У меня был создатель обработчика событий, который взял имя параметра и менял этот параметр каждый раз, когда значение текстового поля изменялось.

const [Obj, setObject] = useState({ID: "", name: "", categories: []})

function changeEventHandlerCreator(name) {
return event => {
  let edittedObject = Object.assign({}, Obj);
  edittedObject[name] = event.target.value;
  setObject(edittedObject);
};

}

Когда я пытался сделать аналогичный метод с вложеннымсвойства категорий / опций, это стало довольно грязно. Я сделал больше создателей обработчиков событий для категорий и опций:

function categoryChangeEventHandlerForCategory(category) {
  return event => {
    let edittedCategory = Object.assign({}, category);
    edittedCategory.categoryName = event.target.value;
    editCategory(edittedCategory, category);
  };
}

function optionChangeEventHandlerForOptionInCategory(option, category) {
  return event => {
    let edittedOption = Object.assign({}, option, {
      optionName: event.target.value
    });
    editOptionInCategory(edittedOption, option, category);
  };
} 

function editCategory(newCategory, oldCategory) {
  let edittedCourse = Object.assign({}, course);
  let edittedCategories = course.categories.map(category =>
    category.categoryID !== oldCategory.categoryID ? category : newCategory
  );
  edittedCourse.categories = edittedCategories;
  setCourse(edittedCourse);
}

function addOptionToCategory(category) {
  let edittedCategory = Object.assign({}, category);
  let option = {
    optionID: nextOptionIndexForCategory(category),
    optionName: "",
    expanded: false
  };
  edittedCategory.options = [option, ...category.options];
  edittedCategory.expanded = true;
  editCategory(edittedCategory, category);
}

Я смог сделать небольшой ярлык здесь. Я знал, что собираюсь редактировать только одно свойство, имя категории / опции, поэтому мне не нужно было заботиться о редактировании нескольких свойств, как я сделал для основного объекта, что облегчило этот метод. Затем я передаю категорию / категорию и параметр создателям дескрипторов событий, чтобы убедиться, что эта функция специально изменяет эту категорию / параметр. Это делается путем отслеживания идентификатора. Создатели обработчиков событий для категорий используют идентификатор, чтобы знать, какая категория / опция редактируется. Это происходит в функции editCategory, где она отображает текущие категории в новый массив, но если идентификатор совпадает с переданной категорией, она возвращает новую категорию вместо старой. То же самое касается параметров редактирования.

Эти обработчики событий передаются компонентам редактора, как показано ниже:

<MainObjEdittor changeEventHandleCreator={changeEventHandlerCreator}/>
{Obj.categories.map(category =>
    <CategoryEdittor categoryChangeEventHandlerForCategory(category)/>
    {category.options.map(option =>
        <OptionEdittor optionChangeEventHandlerForOptionInCategory(option, category)/>
    )}
)}

Мой вопрос заключается в том, является ли это лучшим способом сделать это? Не похоже, что это так. Моя цель - просто иметь возможность редактировать любое свойство любого объекта в основном объекте. Кроме того, если я теперь понимаю, что мне нужно будет редактировать больше, чем просто свойство name категорий и опций, чтобы этот метод не работал (или просто стал бы более грязным). Что было бы хорошим методом для

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...