Выберите inputProps компонента (Material UI)

После этот вопрос я хотел бы заменить компонент TextField (для ввода возраста) на использование компонента Select, поскольку я заметил, что оба имеют свойство inputProps.

Оригинальное приложение:

function App() {
  const [state, setState] = React.useState({
    cats: [{ name: "cat1", age: "2" }, { name: "cat2", age: "5" }],
    owner: "Owner's Name"
  });
  const handleFormChange = e => {
    if (["name", "age"].includes(e.target.dataset.fieldType)) {
      const newCats = [...state.cats];
      newCats[e.target.dataset.id][e.target.dataset.fieldType] = e.target.value;
      setState({ ...state, cats: newCats });
    } else {
      setState({ ...state, [e.target.name]: e.target.value });
    }
  };
  return (
    <form onChange = {handleFormChange}>
      <TextField label = "Owner" value = {state.owner} name = "owner" />
      <br />
      <br />
      <TextField
        label = "Name 1"
        value = {state.cats[0].name}
        inputProps = {{ "data-id": 0, "data-field-type": "name" }}
      />
      <TextField  <-----------------------replace with a Select
        label = "Age 1"
        value = {state.cats[0].age}
        inputProps = {{ "data-id": 0, "data-field-type": "age" }}
      />
    </form>
  );
}

Компонент Select я заменяю вторым TextField:

    <Select
      onChange = {handleSelectChange}
      label = {"Age 1"}
      value = {state.cats[0].age}
      inputProps = {{
        "data-id": idx,
        "data-field-type": "age",
        name: "customName"
      }}
    >
      <MenuItem value = {10}>Ten</MenuItem>
      <MenuItem value = {20}>Twenty</MenuItem>
      <MenuItem value = {30}>Thirty</MenuItem>
    </Select>

Но в моей функции handleSelectChange:

 const handleSelectChange = e => {
    console.info("value", e.target.value); //OK
    console.info("name", e.target.name); // OK
    console.info("dataset", e.target.dataset); //undefined
  };

Атрибуты данных, переданные в inputProps, не определены, почему?

Это codeandbox, который я сделал для тестирования этого поведения: https://codesandbox.io/s/dynamic-form-change-handler-with-select-ft4dj

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

Ответы 1

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

Для Material-UI Select событием, которое запускает onChange, на самом деле является щелчок по MenuItem. Вот немного упрощенная (без учета регистра multiple) версия этот код:

  const handleItemClick = child => event => {
    update(false, event);

    if (onChange) {
      const newValue = child.props.value;

      event.persist();
      event.target = { value: newValue, name };
      onChange(event, child);
    }
  };

Обратите внимание, что цель события явно создается здесь как объект только со свойствами value и name. Первоначальная цель события клика, как правило, бесполезна, поскольку она не будет соответствовать последовательному элементу DOM, представляющему Select, а вместо этого будет некоторым элементом DOM внутри конкретного MenuItem, по которому был выполнен щелчок.

Отвечая на ваш предыдущий вопрос, я избегал начинать дискуссию о том, является ли подход в руководстве хорошим, поскольку я хотел избежать более подробного рассмотрения аспектов, основанных на мнениях; однако этот сценарий вызывает обсуждение. В общем, я думаю, что в React лучше не помещать в DOM лишние вещи, чтобы обработчики событий могли извлечь информацию обратно. Вместо этого просто предоставьте информацию обработчику событий напрямую.

Например, у вас может быть:

  const handleSelectChange = (index, fieldType) => e => {
    console.info("value", e.target.value);
    console.info("name", e.target.name);
    console.info("index", index);
    console.info("fieldType", fieldType);
  };
// then later in the JSX:

            <Select
              onChange = {handleSelectChange(idx, "age")}
              label = {`Cat ${idx + 1} age`}
              value = {state.cats[idx].age}
              inputProps = {{
                name: "customName"
              }}
            >
              <MenuItem value = {10}>Ten</MenuItem>
              <MenuItem value = {20}>Twenty</MenuItem>
              <MenuItem value = {30}>Thirty</MenuItem>
            </Select>

В приведенном выше фрагменте кода индекс и тип поля передаются handleSelectChange, чтобы вернуть обработчик изменений, который знает эту информацию без необходимости быть частью DOM.

Вот модифицированная версия вашей песочницы, в которой работает: https://codesandbox.io/s/dynamic-form-change-handler-with-select-1sihp.

Этот же подход можно использовать и для ввода текста.

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