我有一个将联系人对象存储为状态的组件 - {firstName:" John",lastName:" Doe",phone:" 1234567890}我想创建一个表单来编辑这个对象,但如果我希望输入保持原始联系参数的值,我需要使每个输入成为受控组件。但是,我不知道如何创建一个handleChange函数来调整每个参数,因为我的状态只保存{contact:{...}}。以下是我目前的情况 -
getInitialState: function () {
return ({contact: {}});
},
handleChange: function (event) {
this.setState({contact: event.target.value });
},
render: function () {
return (
<div>
<input type="text" onChange={this.handleChange} value={this.state.contact.firstName}/>
<input type="text" onChange={this.handleChange} value={this.state.contact.lastName}/>
<input type="text" onChange={this.handleChange} value={this.state.contact.lastName}/>
</div>
);
}
我希望在我的处理中改变我可以做类似
的事情 handleChange: function (event) {
this.setState({contact.firstName: event.target.value });
}
答案 0 :(得分:58)
有一个&#34;简单&#34;这样做的方式,以及&#34; smart&#34;办法。如果你问我,以聪明的方式做事并不总是最好的,因为我以后可能会更难以合作。在这种情况下,两者都是可以理解的。
附注:我要求您考虑的一件事是,您是否需要更新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 +。
中的功能要在不同浏览器中支持以下功能,您需要使用Babel使用以下功能来转换代码: 预设es2015和react, 和插件stage-0。
以下是更新的示例,使用object destructuring获取州的联系人,
spread operator来
创建一个更新的联系对象而不是改变现有的联系对象,
将组件创建为Classes
延伸React.Component,
并使用arrow funtions来
创建回调,以便我们不必bind(this)
。
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>
);
}
}
请注意,handleChangeFor
是curried function:
使用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>
);
}
}
答案 1 :(得分:8)
ES6单线方法
<input type="text"
value={this.state.username}
onChange={(e) => this.setState({ username: e.target.value })}
id="username"/>
答案 2 :(得分:2)
有两种方法可以更新嵌套对象的状态:
您可以在此JS Fiddle中查看其工作原理。代码如下:
var Component = React.createClass({
getInitialState: function () {
return ({contact: {firstName: "first", lastName: "last", phone: "1244125"}});
},
handleChange: function (key,event) {
console.log(key,event.target.value);
//way 1
//var updatedContact = JSON.parse(JSON.stringify(this.state.contact));
//updatedContact[key] = event.target.value;
//way 2 (Recommended)
var updatedContact = React.addons.update(this.state.contact, {
[key] : {$set: event.target.value}
});
this.setState({contact: updatedContact});
},
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.phone}/>
</div>
);
}
});
ReactDOM.render(
<Component />,
document.getElementById('container')
);
答案 3 :(得分:1)
这是通用的;
handleChange = (input) => (event) => {
this.setState({
...this.state,
[input]: event.target.value
});
}
并像这样使用;
<input handleChange ={this.handleChange("phone")} value={this.state.phone}/>
答案 4 :(得分:1)
最整洁的方法
这是我在简单应用程序中使用的一种方法。这是React中推荐的方法,它确实干净利落。这非常接近ArneHugo的回答,我也感谢hm。这个想法是混合和反应形式站点。 我们可以使用每个表单输入的name属性来获取特定的propertyName并基于此更新状态。这是我在ES6中的上述示例代码:
class ContactEdit extends React.Component {
handleChangeFor = (event) => {
const name = event.target.name;
const value = event.target.value;
const { contact } = this.state;
const newContact = {
...contact,
[name]: value
};
this.setState({ contact: newContact });
}
render() {
return (
<div>
<input type="text" name="firstName" onChange={this.handleChangeFor} />
<input type="text" name="lastName" onChange={this.handleChangeFor}/>
<input type="text" name="phone" onChange={this.handleChangeFor}/>
</div>
);
}
}
差异:
我们在这里使用的代码更少,并且提供了从表单获取任何类型输入的明智方法,因为name属性对于每个输入将具有唯一的值。 在早期阶段,可以在我的CodPen中进行实验性博客应用程序的工作example。
答案 5 :(得分:0)
<input>
元素通常具有一个名为name的属性。
我们可以从事件处理程序收到的事件对象中访问此名称属性:
编写通用的更改处理程序
constructor () {
super();
this.state = {
name: '',
age: ''
};
this.handleChange = this.handleChange.bind(this);
}
handleChange (evt) {
this.setState({ [evt.target.name]: evt.target.value });
}
render () {
return (
<form>
<label>Name</label>
<input type="text" name="name" onChange={this.handleChange} />
<label>Age</label>
<input type="text" name="age" onChange={this.handleChange} />
</form>
);
}
答案 6 :(得分:0)
updatePrevData=(event)=>{
let eventName=event.target.name;
this.setState({
...this.state,
prev_data:{
...this.state.prev_data,
[eventName]:event.target.value
}
})
console.log(this.state)
}
答案 7 :(得分:0)
您可以做到,无需重复的代码和简单的方法
handleChange=(e)=>{
this.setState({
[e.target.id]:e.target.value
})
}
<Form.Control type="text" defaultValue={this.props.allClients.name} id="clientName" onChange={this.handleChange}></Form.Control>
<Form.Control type="email" defaultValue={this.props.allClients.email} id="clientEmail" onChange={this.handleChange}></Form.Control>
答案 8 :(得分:-2)
handleChange(event){
this.setState({[event.target.name]:event.target.value});
this.setState({[event.target.name]:event.target.value});
}