-
Notifications
You must be signed in to change notification settings - Fork 24.3k
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
fix(android): update text natively only if needed (fixes selection menu missing) #36663
Conversation
Not just in case of a secure text type
Base commit: 04df252 |
Comment from @mdvacca when this logic was first added:
|
@javache Thx for clarifying that. And yes it's right I missed that we work with spannables here. So this code would introduce issues where the native text wouldn't update. Example without this change: Screen.Recording.2023-03-31.at.13.25.26.movExample with this change (broken): Screen.Recording.2023-03-31.at.13.26.37.movI feel like the best solution to address this issue then is to avoid the re-render / the update of the native view when JS updates the selection state to the same as it is in native already. |
Makes sense. Do you want to try and update |
Hm, unfortunately I don't think that would help, as maybeSetText would get executed anyway from the call in Lines 387 to 388 in de2f01d
And the text being replaced is the reason for the selection menu to disappear. I am not sure if there is a feasible solution. We just can't really tell if two Spannables are identical from their content or not (we can, but the solution would be too expensive / complex to run on every re-render). So it feels like the solution to keep the selection menu while manually controlling a |
Closed in favour of #37424 as it successfully fixed the issue without introducing regressions! |
Summary
Problem
There exists a bug where on android when having a controlled
TextInput
using theselection
prop the selection menu would not show up (the first TextInput is uncontrolled and there you can see its working):Screen.Recording.2023-03-27.at.18.48.27.mov
There has also been an issue, which was closed as stale:
The reason for this behaviour is the following:
lastNativeSelectionState
null
lastNativeSelectionState
, causing the component to re-render.maybeSetText
call (e.g. updating the text of the native view)maybeSetText
doesn't check if the text is the same, and updates the texts nativelySolution
We don't want to update the text natively if it hasn't changed. There is already a check present in
maybeSetText
, but it only checks for text changes when the TextInput is a secure one (e.g. a password input).I propose that we always check if the text has changed, and only update the text natively if it really did.
These changes can be seen in this PR.
With these changes you can see that in the tester app the text selection also works for controlled inputs:
Screen.Recording.2023-03-27.at.19.16.49.mov
Changelog
[ANDROID] [FIXED] - Selection menu missing when TextInput uses controlled
selection
propTest Plan
TextInputEventsTestCase
, however I can't find it anywhere in the code. I would like to run those tests and confirm everything is still working as expectedTextInput
in the rn tester app