question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Cursor jumps to end of controlled input

See original GitHub issue

When an input element is “controlled” by a model, the cursor will jump to the end of the line on every change. This makes it impossible to edit text that is not at the end of the input.

A quick demo: https://gist.github.com/ericvicenti/46f97f47c1cfe46040c8

      var ExampleApplication = React.createClass({
        render: function() {
          var model = this.props.model;
          return <input onChange={this.nameChange} value={model.name} />;
        },
        nameChange: function(evt) {
          this.props.model.name = evt.target.value;
        }
      });
      var myModel = {
        name: 'Input is funky'
      };
      setInterval(function() {
        React.renderComponent(
          <ExampleApplication model={myModel} />,
          document.getElementById('container')
        );
      }, 50);

It should be noted that this is only when using an external model, not when using the view’s state. Maybe there is something wrong with my usage here?

As a suggested fix, maybe the input should not be overridden unless the value differs? Otherwise, the cursor position should be manually preserved.

Also, see this SO entry which documents the ability to grab and preserve the cursor position: http://stackoverflow.com/questions/1080532/prevent-default-behavior-in-text-input-while-pressing-arrow-up

Issue Analytics

  • State:closed
  • Created 10 years ago
  • Comments:52 (6 by maintainers)

github_iconTop GitHub Comments

18reactions
rchanoucommented, Apr 1, 2017

I use a light wrapper component to insulate the input value from outside changes when focused. This should be a drop-in replacement for standard input elements.

var Input = React.createClass({
  getDefaultProps(){
    return {
      onChange(){},
      onFocus(){},
      onBlur(){}
    }
  },
  getInitialState(){
    return { 
      isFocused: false, 
      currentValue: this.props.value 
    };
  },
  handleChange(e){
    this.setState({ currentValue: e.target.value });
    this.props.onChange(e);
  },
  handleFocus(e){
    this.setState({ isFocused: true });
    this.props.onFocus(e);
  },
  handleBlur(e){
    this.setState({ isFocused: false });
    this.props.onBlur(e);
  },
  componentWillReceiveProps(nextProps){
    if (!this.state.isFocused){
      this.setState({ currentValue: nextProps.value });
    }
  },
  render(){
    return <input
      {...this.props}
      onChange={this.handleChange}
      onFocus={this.handleFocus}
      onBlur={this.handleBlur}
      value={this.state.currentValue}
    />;
  }
});
18reactions
tsheaffcommented, Oct 23, 2015

@spicyj I’m seeing a similar issue of the cursor jumping to the end whenever I format / modify a controlled input’s value between renders.

Here’s my code:

export default class GiftPurchaseForm extends Component {
  constructor(props) {
    super(props);
    this.state = {
      cardNumber: '',
    };
  }

  cardNumberChanged(event) {
    this.state.cardNumber = event.target.value;
    this.setState(this.state);
  }

  render() {
    return (
      <div id="gift-purchase-form">
        <input
          className="card-number"
          type="text"
          placeholder="Card Number"
          value={creditcard.parse(this.state.cardNumber).formatted}
          onChange={::this.cardNumberChanged}
        />
      </div>
    );
  }
}

creditcard.parse(*).formatted simply turns a number like 4444555566667777 into a card number like 4444 5555 6666 7777

If I remove call to creditcard.parse(*).formatted and just pass this.state.cardNumber the cursor doesn’t jump. But the cursor still jumps even if I pass this.state.cardNumber + '5'; as the next value, so it seems any modification of the string between renders means middle edits (edits before modification point in string) cause cursor to jump to end.

I’m on react@0.14.0

Read more comments on GitHub >

github_iconTop Results From Across the Web

React controlled input cursor jumps - Stack Overflow
If your value is controlled by state, React will maintain the input's cursor position. The problem is when the input receives a change...
Read more >
Solving Caret Jumping in React Inputs - DEV Community ‍ ‍
In a controlled input, React is always capturing the input's events and then forcing a new value into the element. So, in order...
Read more >
Bug: cursor jumps to end of controlled <input> tag when value ...
Make an <input> tag controlled, by setting its value in response to onChange · Apply a transformation to the value (for example, replace...
Read more >
Fix cursor jump to end on input change - CodeSandbox
Activating extension 'vscode.typescript-language-features' failed: Could not find bundled tsserver.js.
Read more >
React: why is my cursor jumping to the end of the input field ...
It works ok but when you are typing in the middle of a string - either add an extra number or delete one...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found