Skip to content

[RFC] onChange -> onInput, and don't polyfill onInput for uncontrolled components #9657

@sebmarkbage

Description

@sebmarkbage

onChange is a nicer name for what onInput does and the fact that it has propagated up to other high-level components as the default name is much nicer than onInput as a high level event name.

Generally it has been helpful for the many new-comers to React that don't know the DOM well (which is a lot more than the inverse). However, that doesn't change the fact that it can be confusing for people that are familiar.

Unfortunately, changing it now would cause confusion for everyone that already knows React.

The reason I'd like to change it now is because I'd like to get away from polyfilling it for uncontrolled components. This use case is filled with all kinds of imperative code which leads to edge cases. E.g. reading/setting e.target.value or reading/setting ref.value.

When you use controlled components you shouldn't need to touch them imperatively and therefore won't hit the edge cases. Ideally we should get away from reading from e.target.value and instead just pass the value directly to the event handler.

Proposal:

Controlled Components

  • onInput: Polyfilled and works like onChange does today. It is allowed to over-fire many events even if nothing changed. May have special Fiber rules regarding synchronous flushing. Optional: Pass value as second arg.
  • onChange: Works like onInput for one version but warns about being deprecated and suggests switching to onInput. In next version it works like the browser but still warns and tells you to use onInput forever.

Optional: Add a getter/setter on DOM .value in development mode and warn if this is used directly.

Uncontrolled Components

  • onInput: Not polyfilled. Works however the browser works. Warns about browser differences if you don't also specify onClick, onKeyDown and/or onKeyUp. The warnings suggests implementing those listeners to cover more edge cases, or switch to a controlled component.
  • onChange: Not polyfilled. Works however the browser works.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions