Я вызываю API, получаю полезную нагрузку и загружаю ее в состояние. Например:
Payload : {
id: 1,
firstName: 'Craig',
surname: 'Smith',
anotherField: 'test data',
....
}
(Обратите внимание, в реальной жизни существует около 20 полей)
На моем экране реакции у меня есть поля для отображения этих данных. На данный момент для каждого поля у меня есть функция onChange. Так:
this.firstnameOnChange = this.firstnameOnChange.bind(this);
а затем функция:
firstnameOnChange() { ....}
Есть ли более простой шаблон, который, возможно, уменьшит количество методов, которые мне нужно создать? Какое-то общее событие OnChange, которое принимает имя и значение, которое затем можно использовать для обновления состояния?
Я могу привязать что-то вроде:
myOnChange(fieldName, value) {
// Somehow find the 'fieldName' in the state and update it's value with 'value'
}
Это действительный образец? Или есть способ лучше? Или мне следует придерживаться отдельных методов OnChange для каждого поля?
Если я могу использовать общий, как мне найти имя поля в состоянии, которое нужно обновить?



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Нет, не рекомендуется записывать onChange для каждого поля. Вы можете написать общий метод onChange следующим образом:
handleChangeEvent= name => event => {
this.setState({payload: {...this.state.payload, [name] : event.target.value}});
}
например, у вас есть такой ввод:
<Input onChange = {this.handleChangeEvent('firstName')} placeholder = "Please Enter" />
PS здесь мы вызываем handleChangeEvent напрямую, поэтому мы используем currying, что означает создание нового экземпляра для каждого вызова. Существует другой подход: извлеките name из event.target и создайте атрибут name во входных данных. Тогда вам не нужно явно передавать имя входа.
Похоже, это сработает для меня. Моя единственная проблема - мои данные «на 1 уровень ниже». Итак, использование [name] не работает, потому что мое значение на самом деле - this.state.payload.firstName. Использование только [name] обновляет this.state.firstName. Как мне получить payload.firstName '?
Я обновил свой ответ. Мы не можем напрямую обновлять наше состояние для вложенных объектов. Это подход к использованию оператора распространения объекта для обновления состояния вложенных объектов.
Поскольку состояние - это объект, это означает, что вы можете обновить его ключ и значение. Все, что вам нужно сделать, это передать правильные параметры общей функции обновления, которая обновит состояние.
Вот один из способов сделать это: https://codesandbox.io/s/v382v6l483
Поскольку ваша полезная нагрузка находится на начальном уровне на один уровень ниже, мы будем использовать оператор распространения и разложить объект полезной нагрузки.
Обновите необходимое значение и, наконец, вернет полезную нагрузку в функцию setState, чтобы обновить состояние и повторно отрендерить компонент.
Вы можете привязать эту функцию к каждому полю и поддерживать свое состояние в актуальном состоянии.
Подробнее об обработке событий и функциях привязки читайте здесь: https://reactjs.org/docs/handling-events.html
<input type = "text" name = "firstname" onChange = {(e) => myOnChange ('firstname', e.target.value}}