-
Notifications
You must be signed in to change notification settings - Fork 24.4k
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
Select text inside TextInput only once from onLayout
#47902
base: main
Are you sure you want to change the base?
Select text inside TextInput only once from onLayout
#47902
Conversation
@dmytrorykun has imported this pull request. If you are a Meta employee, you can view this diff on Phabricator. |
...eact-native/ReactAndroid/src/main/java/com/facebook/react/views/textinput/ReactEditText.java
Outdated
Show resolved
Hide resolved
// Explicitly call this method to select text when layout is drawn | ||
selectAll(); | ||
// Prevent text on being selected for next layout pass | ||
mSelectTextOnFocus = false; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there other cases in Reanimated where props are reapplied multiple times? There are other places where that will cause problems, e.g. for ScrollView setting the contentOffset
prop.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's not strictly Reanimated reapplying props - it's this part of the code:
react-native/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp
Lines 56 to 62 in d86412d
if (!hasBeenMounted && sourceNodeHasRawProps && props) { | |
auto& castedProps = const_cast<Props&>(*props); | |
castedProps.rawProps = mergeDynamicProps( | |
sourceShadowNode.getProps()->rawProps, | |
props->rawProps, | |
NullValueStrategy::Override); | |
return props; |
which relies on the previous node being mounted to apply only the props diff. This assumption is broken by Reanimated at the moment, but it's going to be fixed in the future. I think wrong behavior here was caused by the same field being used to store a prop and the view state at the same time.
@@ -630,6 +631,7 @@ public void maybeUpdateTypeface() { | |||
// VisibleForTesting from {@link TextInputEventsTestCase}. | |||
public void requestFocusFromJS() { | |||
requestFocusInternal(); | |||
hasSelectedTextOnFocus = true; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why do we avoid the onLayout focus here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original PR added this behavior to fix autofocus
and selectTextOnFocus
not working when used together. Since the focus logic was added to onLayout
it may trigger in different cases also, you can see that in the first video (Before
in the table), where the input is focused from JS (with no layout) and then layout change causes the text to be selected even though the focus didn't change.
Summary:
The behavior used for
selectTextOnFocus
changed in #45004. The new behavior relies on the field being set as a prop to keep track whether the text should be focused inonLayout
or not. This causes a problem whenautofocus
is not used - when the layout of the text input changes, the text will get selected even if the focus doesn't change.This also presents itself when the prop is set multiple times. I don't think this can happen in bare React Native, but third-party libraries (such as Reanimated) can cause this path to run:
react-native/packages/react-native/ReactCommon/react/renderer/core/ShadowNode.cpp
Lines 56 to 63 in d424bb9
by cloning the node before it's committed. This behavior (cloning in Reanimated) is not ideal and a replacement is in the works, but in the meantime, it's causing a similar problem where the text will be selected on every layout change.
Changelog:
[ANDROID] [FIXED] - Fixed text being selected multiple times when
selectTextOnFocus
is used on aTextInput
Test Plan:
Code used in the videos
The behavior from the videos doesn't require Reanimated to be reproducible.
Screen.Recording.2024-11-22.at.10.33.43.mov
Screen.Recording.2024-11-22.at.10.33.22.mov
Screen.Recording.2024-11-22.at.10.15.33.mov
Screen.Recording.2024-11-22.at.10.18.29.mov