Skip to content

Cursor jumps to end of input when onChange doesn't call setState #12762

@danielrob

Description

@danielrob

[Edit]: I'm asking for a feature.

Current Behaviour
An input onChange function that returns a value equalling the prior value causes the cursor to jump to the end of the input. This is the same as this comment from #995 formally raised as a feature request.

Repro sandbox: https://codesandbox.io/s/n4k3yx47j
That same code:

import React from "react";
import { render } from "react-dom";

class Input extends React.Component {
  state = { value: "TypeANumber" };

  onChange = e => {
    let nextValue = e.target.value;

    if (/[0-9]/.test(nextValue)) {
      nextValue = this.state.value;
    }
    this.setState({ value: nextValue });
  };

  render() {
    return (
      <input
        type="text"
        value={this.state.value}
        onChange={this.onChange}
      />
    );
  }
}

render(<Input />, document.getElementById("root"));

What is the expected behavior?
I'd like the cursor not to jump in the special case where the returned changed value is a rejected change i.e. the 'noop' change.

I understand fully that react cannot predict cursor position if the value is changed in onChange, however I cannot currently find an npm module that allows free-length regex filters (vs a fixed length mask) or a way to implement a filter myself, without the cursor jumping in this case.

[Edit]:
Since raising I now fully see this as a feature request for handling a special case of a behaviour that indeed is not a bug, differently. It would be a nice to have as it would allow very straightforward implementation of filters.

Regarding the non-clarity of how to deal with the general case of non-jumping cursors I think a modernized best practice example would be ideal, but that discussion still lives at #955.

I'd be totally fine with this issue being closed by assisting instead with the education of handling the general case. Though, this would still be a nice to have for the API, if possible.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions