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

Issue resulting in loss of cursor position in controlled inputs isn't fixed #6563

Closed
deser opened this issue Apr 21, 2016 · 7 comments
Closed

Comments

@deser
Copy link

deser commented Apr 21, 2016

In 15.0.1 release I see "Fixed issue resulting in loss of cursor position in controlled inputs.
@spicyj in #6449"

But actually this bug isn't fixed. Please consider this example:
https://jsfiddle.net/2ayxpag4/4/

Steps to reproduce:

  1. Input 123
  2. Set cursor on 1 position (after 1)
  3. Input something and see that cursor is moved to the end
@syranide
Copy link
Contributor

You must not defer updating the value of the input or the selection information will be lost. I.e., it will think you rejected the change and then updated it, at which point there is no apparent place to put the cursor other than at the end.

@deser
Copy link
Author

deser commented Apr 21, 2016

So then which bug was fixed, could you explain?

@gaearon
Copy link
Collaborator

gaearon commented Apr 21, 2016

The bug that was fixed was related to synchronously updating the input state. This was always supported, and broke in 15.0.0. Asynchronously updating without losing the position was never supported as @syranide noted.

@deser
Copy link
Author

deser commented Apr 21, 2016

Ok, thanks!

@deser
Copy link
Author

deser commented Apr 22, 2016

Sorry but one more question about "You must not defer updating the value of the input or the selection information will be lost": so as all we know setState defers rendering. So my question is why when setState defers rendering cursor isn't lost when I do the same via setTimeout - cursor is lost?

@syranide
Copy link
Contributor

Loosely speaking, setState is not deferring rendering, it's batching updates and executing them immediately when the current React job has finished, there will be no rendering frame in-between. So in a sense, the operation is synchronous with respect to the current rendering frame. setTimeout schedules it for another rendering frame. For all you know setTimeout might execute 10s later and the user has started typing other things in the input field before then. So then 'foobar' does not have any inherent selection information and thus setting the text field to 'foobar' means the only logical place to put the cursor is at the end (or start), whereas when it's done "synchronously" the input field sees that the value produced by the user and its current value (just updated) are the same the next time it renders and it ends up not actually being updated.

@deser
Copy link
Author

deser commented Apr 22, 2016

Thanks for great answer. Now I understand. My last thought is: event when component is rerenderd asynchronously but it's focused I see no problem to set value and preserve cursor. Haven't dug deep but it might work. You may not answer me sorry for taking your time :)

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

No branches or pull requests

3 participants