Description
I would like to make a case for supporting form.reset()
for controlled inputs, and to make control over value and defaultValue more direct.
Background
React synchronizes the value
attribute and the value
property on inputs. I believe this is for two reasons:
- It is easy for testing frameworks like Selenium to select on
[value="*"]
when testing form.reset
reverts an input back to it's value attribute. It also does not trigger change events, which causes input state to be out of sync with React state.
There are many reasons listed in #11896 to stop syncing the value attribute, so I'll keep this issue focused on my desired outcome.
The Change
I want to be able to control the value attribute and property directly from a component, at the same time:
// I won't add Flow types, but this is just for clarity
type Widget {
name: string
}
class EditWidget extends React.Component {
constructor() {
this.state = this.props.widget
}
onChange(event) {
this.setState({ name: event.target.value })
}
render() {
return (
<form>
<input value={this.state.name} defaultValue={this.props.widget.name} onChange={this.onChange} />
<button type="reset">Revert</button>
<button type="submit">Save</button>
</form>
)
}
}
With this change:
- The
value
React property directly maps to the value property - The
defaultValue
React property directly maps to the value attribute - Both
value
anddefaultValue
are configurable at the same time - An input becomes controlled when it specifies a
value
property - Support form.reset, sending synthetic change events for fields that mismatch the last tracked value (or maybe just fire blindly for simplicity)
Why
This change creates a more controlled input, and makes it much clearer how React applies changes. More control is granted to the user. It provides away to allow props coming into a form to dictate a canonical state for the form, while still supporting native browser behavior.
Also, it means that we don't synchronize the value attribute, which would save a lot of headaches 😄.
Things to figure out
Server rendering. What property do we use? In the case, we can only send along the default value. That might be fine for most cases, but I have not thought through the edge cases.