Look at the form to edit phone numbers in Google Contacts.
Let's say my state looks like:
this.state = {
phones: [
{
country: 'US',
label: 'Home',
number: '555'
}
],
};
My HTML would look like, in a loop and simplified to be all text inputs:
<input type="text" value={this.state.phones[index].country} onChange={this.handleChange} />
<input type="text" value={this.state.phones[index].number} onChange={this.handleChange} />
<input type="text" value={this.state.phones[index].label} onChange={this.handleChange} />
How would you implement the handleChange
to call setState
while supporting the fact that it is an array, and that each item in the array has multiple properties?
I saw pieces of answers in other questions, but nothing plete.
Look at the form to edit phone numbers in Google Contacts.
Let's say my state looks like:
this.state = {
phones: [
{
country: 'US',
label: 'Home',
number: '555'
}
],
};
My HTML would look like, in a loop and simplified to be all text inputs:
<input type="text" value={this.state.phones[index].country} onChange={this.handleChange} />
<input type="text" value={this.state.phones[index].number} onChange={this.handleChange} />
<input type="text" value={this.state.phones[index].label} onChange={this.handleChange} />
How would you implement the handleChange
to call setState
while supporting the fact that it is an array, and that each item in the array has multiple properties?
I saw pieces of answers in other questions, but nothing plete.
Share Improve this question asked Jul 5, 2018 at 14:21 Nathan HNathan H 49.5k60 gold badges171 silver badges251 bronze badges 1-
3
If I follow your question correctly you should create a ponent
Phone
which handles it's own state – Paul Fitzgerald Commented Jul 5, 2018 at 14:23
2 Answers
Reset to default 4You can do something like the following and also make a Phone
ponent.
class Phone extends React.Component {
render() {
return (
<div className="App">
<p>{this.props.label}</p>
<input
type="number"
onChange={this.props.updateNumber}
value={this.props.number}
/>
</div>
);
}
}
class App extends React.Component {
state = {
phones: [
{
name: "US",
number: ""
},
{
name: "UK",
number: ""
}
]
};
updateNumber = (e, index) => {
const phones = this.state.phones;
phones[index].number = e.target.value;
this.setState({
phones
});
};
render() {
return (
<div className="App">
{this.state.phones.map((phone, i) => {
return (
<Phone
updateNumber={e => {
this.updateNumber(e, i);
}}
number={this.state.phones[i].number}
label={phone.name}
/>
);
})}
</div>
);
}
}
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare./ajax/libs/react/15.1.0/react-dom.min.js"></script>
<div id='root'></div>
2 options
Make a Phone ponent with it's own state as suggested by Paul Fitzgerald.
Add the index to a
data-index
attribute and check for the value inhandleChange
.
Example of 2:
<input type="text" value={this.state.phones[index].country} data-index="0" onChange={this.handleChange} />
<input type="text" value={this.state.phones[index].number} data-index="0" onChange={this.handleChange} />
<input type="text" value={this.state.phones[index].label} data-index="0" onChange={this.handleChange} />
then in handleChange
:
handleChange(e) {
...
const i = e.target.dataset.index;
...
}