Добавление значений поля ввода к существующему объекту на основе флажка

У меня есть таблица данных, которая отображается через вызов API. Он отображает 4 значения из исходного объекта. Меня в основном волнует значение name, так как это то, что важно позже в почтовом запросе.

Каждая строка в таблице имеет флажок. Когда флажок установлен (true), имя, связанное с этим флажком, добавляется к объекту с именем selectedFields в качестве объекта. Например, если я устанавливаю флажок с именем id, он создает хранилище объектов, например:

  "selectedFields": {
    "id" : {}
  }

Это работает хорошо и хорошо. Однако я добавил 3 поля ввода, связанные с каждым name. Входы lengthType, size, maxArrayElements, которые, конечно, выбираются пользователем. У меня возникли проблемы с добавлением этих значений обратно к объекту, чтобы он выглядел так:

  "selectedFields": {
    "id": {
       lengthType: Variable,
       size: 1,
       maxArrayElements: 1
    },
    "price": {
       lengthType: Fixed,
       size: 10,
       maxArrayElements: 1
    }
  }

Как я могу добавить эти 3 значения обратно к созданному объекту name, чтобы он выглядел как в приведенном выше примере?

Я не хочу публиковать стену кода, поэтому я публикую функцию флажка, которая обрабатывает создание объекта selectedFields с соответствующим выбранным names. Я подозреваю, что входные значения должны быть каким-то образом добавлены сюда, но я не уверен.

 checkbox = ({ name, isChecked }) => {
//handle check box of each fieldName
const obj = this.state.fieldNames.find(field => field.name === name);
if (isChecked === true) {
  //checked conditional
  this.setState(
    {
      selectedFields: {
        ...this.state.selectedFields,
        [name]: {
          ...obj
        }
      }
    },
    () => {
      console.info(
        "callback in  isChecked if conditional",
        this.state.selectedFields
      );
    }
  );
} else {
  const newSelectedFields = this.state.selectedFields;
  delete newSelectedFields[name];
  this.setState(
    {
      selectedFields: newSelectedFields
    },
    () => {
      console.info(
        `box unchecked, deleted from object --->`,
        this.state.selectedFields
      );
    }
  );
}

};

Вам нужно будет сделать первый выбор в раскрывающемся списке для просмотра данных.

Ссылка на CodeSandbox здесь

Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
Улучшение производительности загрузки с помощью Google Tag Manager и атрибута Defer
В настоящее время производительность загрузки веб-сайта имеет решающее значение не только для удобства пользователей, но и для ранжирования в...
Безумие обратных вызовов в javascript [JS]
Безумие обратных вызовов в javascript [JS]
Здравствуйте! Юный падаван 🚀. Присоединяйся ко мне, чтобы разобраться в одной из самых запутанных концепций, когда вы начинаете изучать мир...
Система управления парковками с использованием HTML, CSS и JavaScript
Система управления парковками с использованием HTML, CSS и JavaScript
Веб-сайт по управлению парковками был создан с использованием HTML, CSS и JavaScript. Это простой сайт, ничего вычурного. Основная цель -...
JavaScript Вопросы с множественным выбором и ответы
JavaScript Вопросы с множественным выбором и ответы
Если вы ищете платформу, которая предоставляет вам бесплатный тест JavaScript MCQ (Multiple Choice Questions With Answers) для оценки ваших знаний,...
1
0
295
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Отвечать

Вам нужно изменить несколько вещей, потому что нигде не указано, где назначать новое состояние вне объекта корневого состояния.


Обработчики в вашем Index.js:

Ваши обработчики событий изменения не ищут имя объекта, чтобы определить, существует он или нет. Если вы хотите добавить его к указанному дочернему объекту, убедитесь, что он там есть.

Мы настраиваем обработчики так, чтобы они брали имя объекта и setState с object.assign для этого конкретного объекта, если он существует:

Примечание: поскольку lengthType не имеет свойства name, мы просто предоставляем ему строку. e.currentTarget предоставит параметр span, а не корневой элемент Dropdown, поэтому даже предоставление свойства name этому компоненту не позволит нам использовать e.currentTarget.name — вы можете проконсультироваться с Документация семантического пользовательского интерфейса, если вы предпочитаете что-то другое. Я быстро просмотрел его, но не хотел глубоко погружаться.

  handleChangeEvent = (e, obj_name) => {
    if (this.state.selectedFields[obj_name]) {
      let selectedFields = Object.assign({}, this.state.selectedFields);
      selectedFields[obj_name] = Object.assign(
        this.state.selectedFields[obj_name],
        { [e.target.name]: e.target.value }
      );
      this.setState({ selectedFields });
    }
  };

  onLengthTypeChange = (e, obj_name) => {
    if (this.state.selectedFields[obj_name]) {
      let selectedFields = Object.assign({}, this.state.selectedFields);
      selectedFields[obj_name] = Object.assign(
        this.state.selectedFields[obj_name],
        { lengthType: e.currentTarget.textContent }
      );
      this.setState({ selectedFields });
    }
  };

Вышеупомянутое, конечно, не будет работать, если вы не настроите свои события onChange на своих компонентах так, чтобы в дополнение к вашему объекту события они также отправляли имя вашего объекта.


Обработчики в файле компонента:

Примечание: Это было странно, потому что в вашем файле Index.js вы, кажется, наполовину сделали это с lengthType, но не передали дополнительные данные. Вы не можете просто передать параметры в обработчик — чтобы заставить его работать, вам нужно передать анонимную функцию в свойства onChange, которые будут принимать событие и передавать его функциям обработчика с участием имя вашего объекта:

      <Table.Cell>
        <Dropdown
          placeholder = "Pick a length Type:"
          clearable
          selection
          search
          fluid
          noResultsMessage = "Please search again"
          label = "lengthType"
          multiple = {false}
          options = {lengthTypeOptions}
          header = "Choose a Length Type"
          onChange = {e => onLengthTypeChange(e, name)}
          value = {lengthType}
          required
        />
      </Table.Cell>
      <Table.Cell>
        <Input
          onChange = {e => handleChangeEvent(e, name)}
          value = {this.state.size}
          type = "number"
          name = "size"
          min = "1"
          placeholder = "1"
          required
        />
      </Table.Cell>
      <Table.Cell>
        <Input
          onChange = {e => handleChangeEvent(e, name)}
          value = {this.state.maxArrayElements}
          type = "number"
          name = "maxArrayElements"
          placeholder = "1"
          min = "1"
          max = "100"
          required
        />
      </Table.Cell>

Как только эти вещи будут скорректированы, код обновит указанные свойства дочерних объектов после того, как соответствующий флажок будет выбран.


Последнее примечание:

Я не стал настраивать сохранять предыдущее состояние если снимите флажок а потом чек об оплате ящик. Это не было указано в вашем вопросе, и я не хочу делать предположения.


Песочница кода:

Скорректированная песочница кода: https://codesandbox.io/s/createqueryschema-table-rewrite-bwvo4?fontsize=14


Дополнительные рекомендации:

  • В вашем начальном состоянии ваш selectedFields объявляется как Array, а затем он быстро превращается в Object при установке любого флажка. Я бы предложил этого не делать. Изменение типов данных в свойстве во время работы приложения может привести к большим проблемам.

  • Когда флажок установлен, вы предоставляете функцию checkbox из вашего файла Index.js. Это просто называется box в вашем компоненте. Я бы предложил сохранить имена свойств и эквивалент состояния при передаче от родителя к дочернему элементу. Кому-то гораздо, намного, намного проще прийти и поддерживать, если это необходимо, не говоря уже о том, что легче сохранить собственное здравомыслие.

  • Вышеупомянутая функция checkbox берет свойства от дочернего элемента и передает их родителю. Это будет место для передачи собранных данных в кеш на родительском объекте, в локальное/сеансовое хранилище или во что угодно, что вы хотите сделать со своими данными. Вместо этого вы могли бы написать код для эффекта: если флажок установлен, когда обработчик ввода вызывается делать, сохранение, но я бы сказал, что это, вероятно, было бы лучше на render, так как экран все равно постоянно обновляется, и у вас есть функция checkbox охотно проходящий реквизит в настоящее время. Это предпочтение, так что это ваш выбор


Удачи! Надеюсь, это помогло!

Вы затронули каждую часть, с которой я боролся / задавал вопросы. Спасибо. По вашей первой рекомендации я только что узнал, что selectedFields должен быть массивом объектов (выбранных флажков). "selectedFields": [ { "name": "nameOne", "lengthType": "fixed" .. etc } , { "name": "nameTwo" .. etc } ]

DJ2 31.05.2019 18:30

У меня возникли некоторые проблемы с получением selectedFields желаемого типа/структуры данных, как я упоминал выше. Обработчики изменений тоже нужно переделывать?

DJ2 03.06.2019 16:31

@ DJ2 они не должны быть. Настройка структуры данных в основном выполняется в файле индекса. Что вам нужно сделать, так как вместо того, чтобы находить свойство объекта selectedFields, вы ищете объект в массиве для обновления, вероятно, было бы проще всего: а) filter для объекта, настроить его и заменить это в исходном массиве или б) reduce исходный массив и заменить его возвращенным массивом.

zfrisch 03.06.2019 23:35

Не могли бы вы поделиться основным примером, если это возможно?

DJ2 04.06.2019 00:04

@DJ2 Я могу, но сегодня не смогу. Я работаю над несколькими разными вещами. Тем временем, возможно, стоит создать еще один вопрос.

zfrisch 04.06.2019 00:18

Итак, я опубликовал новый вопрос в другом месте и получил желаемую структуру, но я думаю, что обработчики изменений необходимо обновить, поскольку они больше не добавляются к проверяемому объекту name. codeandbox.io/s/o7jnvlnj0y

DJ2 06.06.2019 17:46

@ DJ2 Извиняюсь, это вылетело из головы. Как-нибудь сегодня посмотрю.

zfrisch 06.06.2019 17:48

не беспокойтесь, сам name больше не является объектом, поэтому его нужно добавить в тот же объект, который содержит name

DJ2 07.06.2019 18:56

Я изменил метод onLengthTypeChange, но все еще не могу получить входные данные для добавления обратно к проверенному [obj_name]

DJ2 10.06.2019 18:52

Как бы вы сохранили предыдущий объект, если флажок не отмечен/отмечен?

DJ2 13.06.2019 22:55

Другие вопросы по теме