Как установить объекты в качестве значений формы в реакции с пользовательским интерфейсом материала?

В настоящее время я пытаюсь создать форму с пользовательским интерфейсом React и Material, где моя конечная полезная нагрузка должна выглядеть так:

{
  title: title,
  quadrants: {
    0: { name: quadrantOne },
    1: { name: quadrantTwo },
    2: { name: quadrantThree },
    3: { name: quadrantFour }
  }
}

Соответствующая часть моей формы (включая начальные значения) устроена следующим образом:

const initialValues = {
  title: '',
  quadrants: {},
};

const [values, setValues] = useState(initialValues);

const handleInputChange = (e: any) => {
  const { name, value } = e.target;
  setValues({
    ...values,
    [name]: value
  });
};

return (
    <Form>
        <Grid item xs = {12} sm = {12}>
          <Input
            name = "title"
            label = "Title"
            value = {initialValues.title}
            onChange = {handleInputChange}
          />
        </Grid>
        <Grid item xs = {12} sm = {6}>
          <Input
            name = "quadrant-one"
            label = "Quadrant 1"
            value = {initialValues.quadrants}
            onChange = {handleInputChange}
          />
        </Grid>
        <Grid item xs = {12} sm = {6}>
          <Input
            name = "quadrant-two"
            label = "Quadrant 2"
            value = {initialValues.quadrants}
            onChange = {handleInputChange}
          />
        </Grid>
    </Form>
)

Таким образом, мои поля ввода выглядят так, так что я не могу ничего вводить в поля:

Но если я что-то ввожу в поля (запись не видна), то получаю следующую полезную нагрузку:

{
  title: "Test"
  quadrants: {}
  quadrant-one: "[object Object]"
  quadrant-two: "[object Object]"
}

Записи не вложены в объект «квадранты», но записи появляются в полезной нагрузке с именем соответствующего элемента формы (например, квадрант-один, квадрант-два...).

Что я делаю неправильно здесь и как я могу это исправить?

Вы передаете и возражаете как значение --> value = {initialValues.quadrants}, возможно, должно быть value = {initialValues.quadrants[0].name}

lissettdm 09.12.2020 16:54

Я знаю, что передавать объект неправильно. Самое смешное, что свойство quadrants — это объект, а не массив. Поэтому я не могу использовать {initialValues.quadrants[0].name}..

Codehan25 09.12.2020 16:58

Да, вы можете использовать initialValues.quadrants[0], попробуйте.

lissettdm 09.12.2020 17:00

@lissettdm Говорит: «Ошибка типа: невозможно прочитать имя свойства неопределенного», когда я использую values.quadrants[0].name. Нужно ли менять структуру квадрантов: {} внутри initialValues?

Codehan25 10.12.2020 08:31
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Навигация по приложениям React: Исчерпывающее руководство по React Router
Навигация по приложениям React: Исчерпывающее руководство по React Router
React Router стала незаменимой библиотекой для создания одностраничных приложений с навигацией в React. В этой статье блога мы подробно рассмотрим...
Массив зависимостей в React
Массив зависимостей в React
Все о массиве Dependency и его связи с useEffect.
1
4
1 490
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Попробуйте эти исправления: -

  • изменить inputvalue с value = {initialValues.title} на value = {values.title}. Поскольку вы уже установили initialValues на statevalues. Событие onChange будет отражено только при обновлении statevalues с помощью setValues. Не непосредственно на const initialValues (сделайте то же самое для остальных входов — только те входы, которые используют valuesstate)

  • function к handleTitleChange()

const handleTitleChange = (e: any) => {
  const { name, value } = e.target;
  
  setValues({
    ...values,
    [name]: value
  });
};
  • function к handleQuadrantChange()
const handleQuadrantChange = (e: any) => {
  const { name, value } = e.target;
  
  setValues({
    ...values,
    quadrants: {
      ...values.quadrants,
      [name]: value
    }
  });
};

Хорошо, но вопрос был связан не с использованием initialState, а с установкой значений объекта внутри квадрантов объекта: {}.

Codehan25 10.12.2020 08:24

Я просто обновляю свой ответ выше. Попробуй

lala 10.12.2020 08:43

Собственно, именно этого я и хотел избежать. Функции точно такие же, поэтому они фактически повторяются. Кроме того, это не решает мою проблему. Таким образом, я не могу вкладывать другие объекты в квадранты: объект {}, как описано в моем вопросе. Проверьте мою необходимую окончательную полезную нагрузку вверху.

Codehan25 10.12.2020 11:07
Ответ принят как подходящий

Вы получаете [Object Object], потому что initialValues.quadrants является объектом, я предполагаю, что вы пытаетесь установить initialValues.quadrants[0].name, но поскольку начальное значение initialValues.quadrants[0] не определено

Вам нужно применить некоторые изменения. Я рекомендую вам определить пользовательский атрибут (индекс данных) для ввода квадрантов, таким образом, при изменении ввода вы можете обновить правильный объект. Также для ввода квадрантов вы можете определить функцию для получения значения, потому что при первом рендеринге значение не определено:

const initialValues = {
    title: "",
    quadrants: {}
  };

  const [values, setValues] = useState(initialValues);

  const handleInputChange = e => {
    const { name, value } = e.target;
    const dataIndex = Number(e.target.getAttribute("data-index"));
    setValues(prev => {
      if (name === "title") {
        return {
          ...prev,
          [name]: value
        };
      } else {
        return {
          ...prev,
          quadrants: {
            ...prev.quadrants,
            [dataIndex]: { name: value }
          }
        };
      }
    });
  };

  const getValue = prop => {
    const value = values.quadrants[prop] ? values.quadrants[prop].name : "";
    return value;
  };

return (
    <Form>
        <Grid item xs = {12} sm = {12}>
          <Input
            name = "title"
            label = "Title"
            value = {values.title}
            onChange = {handleInputChange}
          />
        </Grid>
        <Grid item xs = {12} sm = {6}>
          <Input
            name = "quadrant-one"
            label = "Quadrant 1"
            data-index = "0"
            value = {getValue(0)}
            onChange = {handleInputChange}
          />
        </Grid>
        <Grid item xs = {12} sm = {6}>
          <Input
            name = "quadrant-two"
            label = "Quadrant 2"
            data-index = "1"
            value = {getValue(1)}
            onChange = {handleInputChange}
          />
        </Grid>
    </Form>
)

Работает! Спасибо. Может быть, я создам собственный changeHandler для своих квадрантов, чтобы я мог удалить if внутри setValues.

Codehan25 11.12.2020 09:36

Да, я думаю, что гораздо чище разделить функцию handleInputChange

lissettdm 11.12.2020 12:55

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