[英]How do I edit multiple input controlled components in React?
我有一個組件將聯系人對象存儲為狀態 - {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 我可以做類似的事情
handleChange: function (event) {
this.setState({contact.firstName: event.target.value });
}
有一種“簡單”的方法可以做到這一點,還有一種“聰明”的方法。 如果你問我,以聰明的方式做事並不總是最好的,因為以后可能會更難和我一起工作。 在這種情況下,兩者都是可以理解的。
旁注:我要請您考慮的一件事是,您是否需要更新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 。
下面是更新的示例,使用對象解構從狀態中獲取聯系人, 擴展運算符創建更新的聯系人對象而不是改變現有的對象,通過擴展React.Component將組件創建為類,並使用箭頭函數創建回調,因此我們不必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
是一個handleChangeFor
函數:使用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>
);
}
}
ES6 一種線性方法
<input type="text"
value={this.state.username}
onChange={(e) => this.setState({ username: e.target.value })}
id="username"/>
有兩種方法可以更新嵌套對象的狀態:
你可以在這個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')
);
最簡潔的方法
這是我在我的簡單應用程序中使用的一種方法。 這是React 中推薦的方法,它非常簡潔。 它非常接近 ArneHugo 的回答,我也很感謝。 這個想法是它和反應形式站點的混合。 我們可以使用每個表單輸入的 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 中為我的早期實驗性博客應用程序提供的工作示例。
這是通用的;
handleChange = (input) => (event) => {
this.setState({
...this.state,
[input]: event.target.value
});
}
並像這樣使用;
<input handleChange ={this.handleChange("phone")} value={this.state.phone}/>
<input>
元素通常有一個名為 name 的屬性。 我們可以從我們從事件處理程序接收到的事件對象訪問這個 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>
);
}
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)
}
您可以在沒有重復代碼和簡單方法的情況下做到這一點
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>
handleChange(event){
this.setState({[event.target.name]:event.target.value});
this.setState({[event.target.name]:event.target.value});
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.