Ответ 1
Там есть "простой" способ сделать это и "умный" способ. Если вы спросите меня, что делать, умный способ не всегда лучший, потому что мне может быть труднее работать с ним позже. В этом случае оба варианта вполне понятны.
Боковое примечание. Одна вещь, о которой я прошу вас подумать, - вам нужно обновить объект contact
, или вы можете просто сохранить firstName
и т.д. непосредственно в состоянии? Может быть, у вас много данных в состоянии компонента? Если это так, вероятно, неплохо было бы разделить его на более мелкие компоненты с более узкими обязанностями.
"Простой" способ
changeFirstName: function (event) {
const contact = this.state.contact;
contact.firstName = event.target.value;
this.setState({ contact: contact });
},
changeLastName: function (event) {
const contact = this.state.contact;
contact.lastName = event.target.value;
this.setState({ contact: contact });
},
changePhone: function (event) {
const contact = this.state.contact;
contact.phone = event.target.value;
this.setState({ contact: contact });
},
render: function () {
return (
<div>
<input type="text" onChange={this.changeFirstName.bind(this)} value={this.state.contact.firstName}/>
<input type="text" onChange={this.changeLastName.bind(this)} value={this.state.contact.lastName}/>
<input type="text" onChange={this.changePhone.bind(this)} value={this.state.contact.phone}/>
</div>
);
}
"умный" способ
handleChange: function (propertyName, event) {
const contact = this.state.contact;
contact[propertyName] = event.target.value;
this.setState({ contact: contact });
},
render: function () {
return (
<div>
<input type="text" onChange={this.handleChange.bind(this, 'firstName')} value={this.state.contact.firstName}/>
<input type="text" onChange={this.handleChange.bind(this, 'lastName')} value={this.state.contact.lastName}/>
<input type="text" onChange={this.handleChange.bind(this, 'phone')} value={this.state.contact.lastName}/>
</div>
);
}
Обновление: те же примеры, что и для ES2015 +
В этом разделе содержатся те же примеры, что показаны выше, но с использованием функций из ES2015 +.
Чтобы поддерживать следующие функции в браузерах, вам необходимо передать ваш код Babel, используя, например, пресеты es2015 и react, и плагин stage-0.
Ниже приведены обновленные примеры, используя разрушение объектов, чтобы получить контакт из состояния,
распространить оператор на
создайте обновленный контактный объект вместо мутирования существующего,
создавая компоненты как Classes
расширяя React.Component,
и используя функции стрелок до
создавать обратные вызовы, поэтому нам не нужно bind(this)
.
"Простой" способ, ES2015 +
class ContactEdit extends React.Component {
changeFirstName = (event) => {
const { contact } = this.state;
const newContact = {
...contact,
firstName: event.target.value
};
this.setState({ contact: newContact });
}
changeLastName = (event) => {
const { contact } = this.state;
const newContact = {
...contact,
lastName: event.target.value
};
this.setState({ contact: newContact });
}
changePhone = (event) => {
const { contact } = this.state;
const newContact = {
...contact,
phone: event.target.value
};
this.setState({ contact: newContact });
}
render() {
return (
<div>
<input type="text" onChange={this.changeFirstName} value={this.state.contact.firstName}/>
<input type="text" onChange={this.changeLastName} value={this.state.contact.lastName}/>
<input type="text" onChange={this.changePhone} value={this.state.contact.phone}/>
</div>
);
}
}
"умный" способ, ES2015 +
Обратите внимание, что handleChangeFor
является функцией curried:
Вызов с помощью propertyName
создает функцию обратного вызова, которая при вызове обновляет [propertyName]
(новый) контактный объект в состоянии.
class ContactEdit extends React.Component {
handleChangeFor = (propertyName) => (event) => {
const { contact } = this.state;
const newContact = {
...contact,
[propertyName]: event.target.value
};
this.setState({ contact: newContact });
}
render() {
return (
<div>
<input type="text" onChange={this.handleChangeFor('firstName')} value={this.state.contact.firstName}/>
<input type="text" onChange={this.handleChangeFor('lastName')} value={this.state.contact.lastName}/>
<input type="text" onChange={this.handleChangeFor('phone')} value={this.state.contact.lastName}/>
</div>
);
}
}