Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[RFC] Enabling form.reset() on controlled inputs, make value and defaultValue more transparent #8011

Closed
nhunzaker opened this issue Oct 19, 2016 · 5 comments

Comments

@nhunzaker
Copy link
Contributor

nhunzaker commented Oct 19, 2016

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:

  1. It is easy for testing frameworks like Selenium to select on [value="*"] when testing
  2. 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:

  1. The value React property directly maps to the value property
  2. The defaultValue React property directly maps to the value attribute
  3. Both value and defaultValue are configurable at the same time
  4. An input becomes controlled when it specifies a value property
  5. 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.

@syranide
Copy link
Contributor

If you have controlled inputs you already have a sanctioned way of resetting them, using .reset() for that purpose just seems sloppy?

@nhunzaker
Copy link
Contributor Author

nhunzaker commented Oct 19, 2016

I disagree. It's intuitive that inputs, which already get significant treatment to normalize change event behavior, would trigger a change when a form resets.

My primary motivation is, of course, to address edge cases with special inputs types in Chrome, but this also makes forms more resilient.

Instead of fighting against the browser, it plays nice.

@nhunzaker nhunzaker changed the title Enabling form.reset() on controlled inputs (and how it relates to fixing Chrome number inputs) [RFC] Enabling form.reset() on controlled inputs (and how it relates to fixing Chrome number inputs) Oct 30, 2016
@nhunzaker nhunzaker changed the title [RFC] Enabling form.reset() on controlled inputs (and how it relates to fixing Chrome number inputs) [RFC] Enabling form.reset() on controlled inputs Oct 30, 2016
@nhunzaker
Copy link
Contributor Author

I've updated the title. I ended up going with an alternative approach to fix Chrome's input issues for #7359, but I'd love to keep talking about this.

@nhunzaker nhunzaker changed the title [RFC] Enabling form.reset() on controlled inputs [RFC] Enabling form.reset() on controlled inputs, make value and defaultValue more transparent Aug 31, 2018
@nhunzaker
Copy link
Contributor Author

It's been a long time, but I've updated the description of this issue to provide a more coherent description of my proposal.

@nhunzaker
Copy link
Contributor Author

With the discussion in #13526, I believe this should be closed. The behavior of value and defaultValue is inline with this RFC, and the form reset behavior has been settled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants