Создание обобщенной функции onChange() для разных входных данных без использования тега имени

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

Для моего проекта я использую дизайн Ant, который, похоже, не поддерживает атрибут имени внутри своих элементов формы (например, InputNumber/Input и т. д.).

Пример поля InputNumber:

<InputNumber name='myNumber' min = {1} max = {100000} placeholder='Enter number'  value = {this.state.myNumber} onChange = {handleChangeEvent}/>

Это моя попытка написать обобщенный метод onChange. Но он передает эту ошибку: Не удается прочитать имя свойства неопределенного

 handleChangeEvent = (e) => {
    this.setState({
      [e.target.name]: e.target.value
    });

Этот метод позволит мне получить доступ к любому выбранному элементу ввода и обновить его. Однако это работает из-за отсутствия атрибута имени.

Как предлагается ниже, этот подход работает, но по-прежнему оставляет меня без обобщенного решения — способа обработки любого ввода и сопоставления с правильным значением состояния.

state = {
    myNumber: 0,
    myNumber2: 0,
    myNumber3: 0
  };

  handleChangeEvent = e => {
    this.setState({
      myNumber: e
    });
  };

В приведенном ниже примере функция handleChangeEvent будет обновлять только myNumber, но не myNumber2 и myNumber3.

<InputNumber name='myNumber' min = {1} max = {100000} placeholder='Enter number'  value = {this.state.myNumber} onChange = {handleChangeEvent}/>
<InputNumber name='myNumber2' min = {1} max = {100000} placeholder='Enter number'  value = {this.state.myNumber2} onChange = {handleChangeEvent}/>
<InputNumber name='myNumber3' min = {1} max = {100000} placeholder='Enter number'  value = {this.state.myNumber3} onChange = {handleChangeEvent}/>

Любые предложения по обходному пути?

На данный момент единственное предлагаемое мной решение — перестроить мой проект с помощью Material-UI. Я протестировал эту функцию в проекте с использованием Material UI, и она сработала, потому что они поддерживают атрибут «имя». Я предпочитаю дизайн Ant Design, поэтому я все равно был бы признателен за обходной путь, если это возможно.

Lars-August Johnson 08.07.2019 15:27

Ваш вопрос слишком заморочен, что значит "обобщенный метод onChange"? Как вы оцениваете поведение своего компонента? Проверьте мой ответ, хотя я думаю, вам следует подробнее остановиться на конкретных примерах.

Dennis Vash 08.07.2019 16:46

Более того, «мое единственное предлагаемое решение - перестроить мой проект с использованием Material-UI» - очень плохое предложение, рефакторинг проекта, потому что «недостаток знаний» - это плохой совет.

Dennis Vash 08.07.2019 16:47

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

Lars-August Johnson 09.07.2019 09:33

ПОКАЖИТЕ пример использования, попробуйте прочитать свой вопрос, как вы думаете, люди могут понять, чего вы пытаетесь достичь?

Dennis Vash 09.07.2019 09:33

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

Lars-August Johnson 09.07.2019 09:41

Отлично, теперь ясно

Dennis Vash 09.07.2019 09:42
Поведение ключевого слова "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
7
176
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

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

Согласно InputNumber API, onChange принимает Number|String, e.target.value всегда устраняет ошибку времени выполнения.

onChange: The callback triggered when the value is changed - function(value: number | string)

Вот пример, где я полагаю в письменной форме:

<InputNumber name='myNumber' min = {1} max = {100000} placeholder='Enter number'  value = {this.state.myNumber} onChange = {handleChangeEvent}/>

Вы имели в виду использование компонента класса, потому что onChange = {handleChangeEvent}, как вы описали, должен быть частью класса.

export default class App extends React.Component {
  state = {
    myNumber: 0
  };

  handleChangeEvent = e => {
    this.setState({
      myNumber: e
    });
  };

  render() {
    return (
      <FlexBox>
        <InputNumber
          name = "myNumber"
          min = {1}
          max = {100000}
          placeholder = "Enter number"
          value = {this.state.myNumber}
          onChange = {this.handleChangeEvent}
        />
      </FlexBox>
    );
  }
}

Edit Q-56934468-InputNumber


  • Если вы хотите использовать общий метод handleChangeEvent, вы должны изменить тип компонента с InputNumber на Input, потому что вы хотите получить доступ к свойству name = "myNumber".
handleChangeEvent = e => {
  e.persist();
  this.setState({
    [e.target.name]: e.target.value
  });
};
  • Лучший подход продолжает использовать InputNumber и реализовать handleChangeEvent как каррированную функцию:
handleChangeEvent = name => e => {
  this.setState({
    [name]: e
  });
};

Проверьте пример обоих подходов:

class AppInputNumber extends React.Component {
  state = {
    myNumber: 0,
    myNumber2: 0,
    myNumber3: 0
  };

  handleChangeEvent = name => e => {
    this.setState({
      [name]: e
    });
  };

  render() {
    return (
      <FlexBox>
        <InputNumber
          min = {1}
          max = {100000}
          placeholder = "Enter number"
          value = {this.state.myNumber}
          onChange = {this.handleChangeEvent('myNumber')}
        />
        <InputNumber
          min = {1}
          max = {100000}
          placeholder = "Enter number"
          value = {this.state.myNumber2}
          onChange = {this.handleChangeEvent('myNumber2')}
        />
        <InputNumber
          min = {1}
          max = {100000}
          placeholder = "Enter number"
          value = {this.state.myNumber3}
          onChange = {this.handleChangeEvent('myNumber3')}
        />
      </FlexBox>
    );
  }
}

export default class App extends React.Component {
  state = {
    myNumber: 0,
    myNumber2: 0,
    myNumber3: 0
  };

  handleChangeEvent = e => {
    e.persist();
    this.setState({
      [e.target.name]: e.target.value
    });
  };

  render() {
    return (
      <FlexBox>
        <Input
          name = "myNumber"
          min = {1}
          max = {100000}
          type = "number"
          placeholder = "Enter number"
          value = {this.state.myNumber}
          onChange = {this.handleChangeEvent}
        />
        <Input
          name = "myNumber2"
          min = {1}
          max = {100000}
          type = "number"
          placeholder = "Enter number"
          value = {this.state.myNumber2}
          onChange = {this.handleChangeEvent}
        />
        <Input
          name = "myNumber3"
          min = {1}
          max = {100000}
          type = "number"
          placeholder = "Enter number"
          value = {this.state.myNumber3}
          onChange = {this.handleChangeEvent}
        />
        <AppInputNumber />
      </FlexBox>
    );
  }
}

Edit Q-56934468-GenericHandle


Спасибо за ответ! Это позволяет мне достичь значения, но моя цель — создать обобщенный метод handleChangeEvent. Как бы вы предложили мне сделать это с помощью этого метода?

Lars-August Johnson 09.07.2019 09:06

Что значит обобщенный метод? Отредактируйте свой вопрос и добавьте пример использования, ожидаемое поведение и т. д.

Dennis Vash 09.07.2019 09:08

Спасибо за ответ Денис! Я попытался обновить свой оригинальный пост, чтобы быть более конкретным.

Lars-August Johnson 09.07.2019 09:33

Ответ обновлен, если он был полезен, примите ответ и проголосуйте. Кроме того, пожалуйста, возьмите Тур и прочитайте Как задать хороший вопрос для своего следующего поста ;-) Получайте удовольствие.

Dennis Vash 09.07.2019 10:01

Деннис Вэш, ты легенда. Это сработало отлично, спасибо! Извините, но у меня всего 6 репутации, поэтому мой апвоут не визуализируется, а записывается.

Lars-August Johnson 09.07.2019 10:20

Я не уверен, но если e является объектом события, попробуйте это

e.target.getAttribute('name')

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