Skip to content

Properly enable Pressable after disabled prop reset - #58799

Closed
bigcupcoffee wants to merge 1 commit into
react:mainfrom
bigcupcoffee:fix/android-set-enabled
Closed

bigcupcoffee wants to merge 1 commit into
react:mainfrom
bigcupcoffee:fix/android-set-enabled

Conversation

@bigcupcoffee

@bigcupcoffee bigcupcoffee commented Oct 1, 2026 •

Copy link
Copy Markdown
Contributor

Summary:

JSI drops undefined keys, so reseting disabled from true to undefined on Touchables/Pressables never runs setEnabled(true)

There is props diffing feature flag that fixes this, which is off by default

Also added safety check against explicit null & reset on recycling

Fixes #56777 and supersedes #58795

Changelog:

[ANDROID] [FIXED] - Properly enable Pressable after disabled prop resets from true

Test Plan:

Added BaseViewManagerTest as well as videos of testing it on Pressable:

before.mov
after.mov

@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 1, 2026
@facebook-github-tools facebook-github-tools Bot added the Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team. label Oct 1, 2026
@meta-codesync

meta-codesync Bot commented Oct 1, 2026

Copy link
Copy Markdown

@zeyap has imported this pull request. If you are a Meta employee, you can view this in D122872380.

@meta-codesync meta-codesync Bot closed this in 357b699 Oct 2, 2026
@meta-codesync meta-codesync Bot added the Merged This PR has been merged. label Oct 2, 2026
@meta-codesync

meta-codesync Bot commented Oct 2, 2026

Copy link
Copy Markdown

@zeyap merged this pull request in 357b699.

fabriziocucci added a commit that referenced this pull request Oct 5, 2026
Summary:
JSI drops `undefined` keys, so reseting `disabled` from `true` to `undefined` on Touchables/Pressables never runs `setEnabled(true)`

There is props diffing feature flag that fixes this, which is off by default

Also added safety check against explicit `null` & reset on recycling

Fixes #56777 and supersedes #58795

## Changelog:

[ANDROID] [FIXED] - Properly enable Pressable after `disabled` prop resets from `true`

Pull Request resolved: #58799

Test Plan:
Added BaseViewManagerTest as well as videos of testing it on Pressable:

https://github.com/user-attachments/assets/e9a7dcd2-46d5-4cdc-88a3-728bff22e76b

https://github.com/user-attachments/assets/043150ae-64f2-47c9-b13c-abfec5b61747

Reviewed By: javache

Differential Revision: D122872380

Pulled By: zeyap

fbshipit-source-id: f3f1cad378f36f006bbb6c7f3f2e4f9aa8e61541
(cherry picked from commit 357b699)
meta-codesync Bot pushed a commit that referenced this pull request Oct 16, 2026
Summary:
With `enableViewRecycling` on, a recycled view keeps the accessibility state its previous props applied. `BaseViewManager.prepareToRecycleView` clears the accessibility tags, but not the content description, `importantForAccessibility`, the selected state, the live region, `screenReaderFocusable`, the `role` and collection tags, or the actions its accessibility delegate cached. The next view of that type is built from it and applies only the props it declares, so TalkBack announces a label and a role the view never had, the delegate sends TalkBack's click to an action only the previous props declared, and a view last used inside an `aria-hidden` subtree hides its new content from accessibility services. With `experimental_accessibilityOrder` on as well, a recycled `ReactViewGroup` keeps its previous order list, and a recycled child keeps the parent and focusability tags its former parent's order put on it.

This resets that state in `prepareToRecycleView` to what a new view has, clears the order list in `ReactViewGroup.initView`, and restores `TextView`'s default importance in `ReactTextView.recycleView`. The delegate stays, since `ReactScrollView`, `ReactHorizontalScrollView` and `ReactNestedScrollView` install theirs in their constructors: a new `ReactAccessibilityDelegate.prepareToRecycle()` clears the actions it cached, and `accessibilityLabelledBy`, read only in the call that sets it, is a local there. It sits beside the `enabled` reset #58799 added.

## Changelog:

[ANDROID] [FIXED] - Recycled views no longer keep the accessibility state of their previous props

Pull Request resolved: #59047

Test Plan:
New cases in `BaseViewManagerTest` and `ReactTextViewPropertyTest` recycle a view through `onDropViewInstance` and `createView` and compare it with a new one. Before the change six fail: content description `"Dismiss sheet"`, `role` tag `LIST`, a click dispatched to the previous props' `activate` action instead of performed, importance `4` where a new text view has `1`, the order list `["first"]`, and the former parent in `accessibility_order_parent`. Another case recycles each scroll view and checks that it keeps the `ReactScrollViewAccessibilityDelegate` its constructor installed. With the change, `./gradlew :packages:react-native:ReactAndroid:testDebugUnitTest -PenableWarningsAsErrors=true` passes (727 tests) and the release sources compile with the same flag; the RNTester debug build and the rest of `build_android` were not run.

RNTester with view recycling on, on an Android 16 emulator with TalkBack, [before and after](#59047 (comment)): plain rows mounted after labelled rows were removed are read as a selected "Dismiss sheet" button without the change, and as their text with it.

On a Galaxy S23 (Android 14) app with view recycling on, plain rows mounted after rows carrying `aria-label`, `role`, `aria-selected`, `aria-disabled` and `aria-hidden` were removed reported the removed rows' label as their content description before the change. Built from source with it, the same rows report no label, role, selected or disabled state, and their text is in the accessibility tree.

Both device runs used the first revision of this change, which cleared the delegate on recycle instead of resetting it.

Reviewed By: Abbondanzo

Differential Revision: D125427268

Pulled By: javache

fbshipit-source-id: 1dad635ef6f1e5cef351d355865edc567f7bce58
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. Merged This PR has been merged. Shared with Meta Applied via automation to indicate that an Issue or Pull Request has been shared with the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Android][0.84.1] TouchableOpacity only receives onPress on text area after disabled-to-enabled transition

1 participant