Add "Handling Multiple Inputs" to Forms doc #8552
| +When you need to handle multiple controlled `input` elements, you can add a `name` attribute to each element and let a handler function choose what to do based on the value of `event.target.name`. For example: | ||
| + | ||
| +```javascript{14-15,18,32,38} | ||
| +class RSVP extends React.Component { |
| + pendingState[event.target.name] = event.target.value; | ||
| + break; | ||
| + default: | ||
| + // the code should never reach here |
| + name="numberOfGuests" | ||
| + type="number" | ||
| + value={this.state.numberOfGuests} | ||
| + onChange={this.handleInputChange} |
I think two inputs here means too much mental overhead. Let's just use one input for example?
|
How do you feel about using the example in #8769 (comment) instead? |
|
@gaearon sounds great to me! That's more clear than my example. Sorry, I've been traveling and didn't see your comments -- will update this PR by tomorrow. |
|
Hey @gaearon, I revisited your example again carefully and I realized that our approaches are actually different. If I use your pattern to render a form with multiple input types, it quickly becomes more complex: class MyComponent extends React.Component {
constructor(props) {
super(props);
this.state = {
name: 'Jane',
surname: 'Smith',
isGoing: false,
};
}
handleChange(name, e) {
if (name === 'isGoing') {
this.setState({
[name]: e.target.checked // a `checkbox` has `.checked` but not `.value`
});
} else {
this.setState({
[name]: e.target.value
});
}
}
renderInput(name) {
if (name === 'isGoing') {
return (
<input
type="checkbox"
onChange={e => this.handleChange(name, e)}
value={this.state[name]}
/>
);
}
return (
<input
type="text"
onChange={e => this.handleChange(name, e)}
value={this.state[name]}
/>
);
}
render() {
return (
<div>
{this.renderInput('name')}
{this.renderInput('surname')}
{this.renderInput('isGoing')}
</div>
);
}
}It also creates more level of redirections (mental overhead) and closures ( How do you feel about using my example in the PR? I might be subjective on this and would love to have your feedback. |
| + | ||
| + handleInputChange(event) { | ||
| + const pendingState = {}; | ||
| + switch (event.target.name) { |
Why don’t we switch on the event target type instead?
I would prefer a more succinct version (since that's what the example tries to convey):
handleInputChange(e) {
const value = e.target.type === 'checkbox' ? e.checked : e.value;
const name = e.target.name;
this.setState({
[name]: value
});| @@ -186,7 +186,7 @@ Overall, this makes it so that `<input type="text">`, `<textarea>`, and `<select | ||
| When you need to handle multiple controlled `input` elements, you can add a `name` attribute to each element and let a handler function choose what to do based on the value of `event.target.name`. For example: | ||
| -```javascript{14-15,18,32,39} |
I've already updated the Codepen! Is there anything specific that needs improvement? :)
|
W dniu środa, 18 stycznia 2017 Keyan Zhang <[email protected]>
napisał(a):
…
|
It was brought up on this blog post (search for "Working with forms and Redux in React") and on Hacker News.
To be fair, this is a pretty common pattern of handling multiple inputs and it's not intuitive for someone to realize the
nameattribute can be used to achieve this. I think it's worth it to add it to the Forms section.