Skip to content

Re-land - Genalize focus/blur behavior in JS - #54085

Closed
sbuggay wants to merge 1 commit into
react:mainfrom
sbuggay:export-D84082783
Closed

Re-land - Genalize focus/blur behavior in JS#54085
sbuggay wants to merge 1 commit into
react:mainfrom
sbuggay:export-D84082783

Conversation

@sbuggay

@sbuggay sbuggay commented Oct 7, 2025

Copy link
Copy Markdown
Contributor

Summary:
Re-land generalized focus/blur commands.

Changelog: [Internal]

Differential Revision: D84082783

@meta-codesync

meta-codesync Bot commented Oct 7, 2025

Copy link
Copy Markdown

@sbuggay has exported this pull request. If you are a Meta employee, you can view the originating Diff in D84082783.

@meta-cla meta-cla Bot added the CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. label Oct 7, 2025
@sbuggay
sbuggay force-pushed the export-D84082783 branch 2 times, most recently from 8bc27b4 to b7686ce Compare October 8, 2025 16:06
@sbuggay
sbuggay force-pushed the export-D84082783 branch 2 times, most recently from 7164a18 to 829ed64 Compare October 8, 2025 19:21
rozele pushed a commit to rozele/react-native-macos that referenced this pull request Oct 8, 2025
Summary:
Pull Request resolved: react#54085

Re-land generalized focus/blur commands.

Changelog: [Internal]

Differential Revision: D84082783

Reviewed By: rozele
Summary:

Re-land generalized focus/blur commands.

Changelog: [Internal]

Reviewed By: rozele

Differential Revision: D84082783
@meta-codesync meta-codesync Bot closed this in e3a5af6 Oct 9, 2025
@facebook-github-bot facebook-github-bot added the Merged This PR has been merged. label Oct 9, 2025
@meta-codesync

meta-codesync Bot commented Oct 9, 2025

Copy link
Copy Markdown

This pull request has been merged in e3a5af6.

@react-native-bot

Copy link
Copy Markdown
Collaborator

This pull request was successfully merged by @sbuggay in e3a5af6

When will my fix make it into a release? | How to file a pick request?

meta-codesync Bot pushed a commit that referenced this pull request Jul 20, 2026
…oid keyboard staying open) (#57584)

Summary:
Since #54085 ("Genalize focus/blur behavior in JS"), `ReactNativeElement.blur()` looks at `TextInputState.isTextInput(this)` to check if the text input is registered in the set before attempting to send the native command to blur.

`TextInput`'s unmount cleanup runs in this order:

```js
TextInputState.unregisterInput(inputRefValue);          // removes it from the set
if (TextInputState.currentlyFocusedInput() === inputRefValue) {
  nullthrows(inputRefValue).blur();                     // isTextInput() now false -> no-op
}
```

Since the input is unregistered first, `blur()` doesn't do anything: the native blur command is not dispatched. `unregisterInput` deletes the text input id from the set.

On Android the visible symptom is that **the soft keyboard stays open after unmounting a focused TextInput**. Navigating back from a native-stack screen with a focused input will try to focus whatever focusable view remains in the window (a WebView, an SDK overlay, etc.), which then "owns" the stuck keyboard. Apps with no other touch-mode-focusable views don't see it (focus falls to null and Android hides the keyboard itself), which is likely why it went unnoticed.

This PR reorders the cleanup so `blur()` runs while the input is still registered, restoring the pre-0.83 behavior. This mirrors the fix #54085 itself applied on the `focus()` side, where `registerInput()` was moved into the ref callback so `focus()` could be called before the layout effect registers the input.

Bisect: 0.79.7 / 0.81.6 / 0.82.1 unaffected -> 0.83.0 broken -> reproduced through 0.86.0.

## Changelog:

[GENERAL] [FIXED] - TextInput: blur focused input before unregistering it on unmount, fixing the Android soft keyboard staying open after navigating away from a focused input

Pull Request resolved: #57584

Test Plan:
- New Fantom test in `TextInput-itest.js`: `dispatches the blur command when a focused input is unmounted` — asserts the `blur` command is dispatched and `TextInput.State.currentlyFocusedInput()` is cleared. Fails before this change, passes after.

I manually reproduced the bug and the bug fix with the following:
- React Native at 86
- `react-navigation/native-stack`
- `react-native-screens`
- `react-native-webview`

The app has 2 screens: Screen A has a webview and Screen B has an input that is auto-focused.
1. User navigates from Screen A -> Screen B
2. The input is auto-focused. They keyboard opens
3. The user presses the back button and navigates to Screen B
4. The webview can still hold focus (according to Android OS) so the keyboard stays open

Reviewed By: rozele

Differential Revision: D112806265

Pulled By: fabriziocucci

fbshipit-source-id: ff410c819d5f49dc000d204e07eebf0fda91876e
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CLA Signed This label is managed by the Facebook bot. Authors need to sign the CLA before a PR can be reviewed. fb-exported Merged This PR has been merged. meta-exported p: Facebook Partner: Facebook Partner

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants