Summary:
With TalkBack on, a `ScrollView` that has `accessibilityCollection` set crashes the app as soon as any direct child of its content view lacks `accessibilityCollectionItem` — e.g. a FlatList `ListHeaderComponent` or `ListFooterComponent`. It reproduces on a common path: a screen reader user navigating away from a list screen. In release builds there is no red box; the process just dies.
```
java.lang.NullPointerException: null cannot be cast to non-null type com.facebook.react.bridge.ReadableMap
at ReactScrollViewAccessibilityDelegate.onInitializeAccessibilityEventInternal(ReactScrollViewAccessibilityDelegate.kt:74)
...
at android.view.View.clearAccessibilityFocus(View.java:15215)
at android.view.ViewGroup.removeViewInternal(ViewGroup.java:5611)
at com.facebook.react.fabric.mounting.SurfaceMountingManager.removeViewAt(SurfaceMountingManager.kt:493)
```
The cause is a non-null cast on a value the code expects to be null:
```kotlin
var accessibilityCollectionItem: ReadableMap? =
nextChild.getTag(R.id.accessibility_collection_item) as ReadableMap // throws on null
...
// If this child's accessibilityCollectionItem is null, we'll check one more nested child.
if (nextChild.childCount > 0 && accessibilityCollectionItem == null) {
```
The variable is declared nullable and the null branch right below it was written for exactly this case, but the `as` cast throws before that branch can run. This PR changes it to `as?`, matching the other tag reads in the same file. No behavior change for children that do carry the tag.
It has gone unnoticed because no React Native component sets `accessibilityCollection` itself (it was added in 105a2397b6 for https://github.com/react/react-native/issues/30977), so the early return at the top of the method skips this code for core lists. Any library that sets it to announce a windowed list's real length hits the crash immediately. Observed on 0.87.1 (API 36, new architecture, Hermes); details in https://github.com/iray-tno/hozo/issues/512.
## Changelog:
[ANDROID] [FIXED] - Fix crash in ScrollView accessibility delegate when `accessibilityCollection` is set and a child (e.g. a list header or footer) has no `accessibilityCollectionItem`
Pull Request resolved: https://github.com/react/react-native/pull/58660
Test Plan:
- One-token change (`as` → `as?`); the assigned variable is already `ReadableMap?` and all later uses are null-checked, so types are unchanged.
- Not built or tested locally: the environment had no Android SDK. Relying on CI for the Android build.
- Repro (before this change): Android + TalkBack, a `FlatList` with `ListHeaderComponent`, `accessibilityCollection` on the list and `accessibilityCollectionItem` on cells only; put accessibility focus inside the list and unmount the screen → crash above. Expected after: no crash.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Reviewed By: Abbondanzo
Differential Revision: D121556760
Pulled By: cortinico
fbshipit-source-id: ccbfe470dc53adec3deac3458b83ae2bc08a48cb
Learn once, write anywhere:
Create native apps for Android, iOS, and more using React
Getting Started · Learn the Basics · Showcase · Contribute · Community · Support
React Native
React Native lets you build native apps using React. Written in JavaScript, rendered with native code.
- Native UI. React Native primitives render to native platform UI, meaning your app uses the same native platform APIs other apps do. Gestures, text scaling, and accessibility behave the way users expect on each OS.
- React, everywhere. Declarative UI, components, hooks, and Suspense, reused across Android, iOS, and other platforms.
- Developer Velocity. See local changes in seconds. Changes to JavaScript code are applied with Fast Refresh, without rebuilding the native app.
- Extend it yourself. Native Modules let you call platform code directly from JavaScript, synchronously and type-safe — or reach for thousands of existing libraries.
React Native is developed and supported by many companies and individual core contributors. Find out more on the React Foundation website.
Building your first React Native app
Follow the Getting Started guide for a new app, or Integration with Existing Apps to adopt React Native incrementally.
Using a Framework
We believe that the best way to experience React Native is through a Framework, a toolbox with all the necessary APIs to let you build production ready apps. Expo is a production-grade React Native Framework, with file-based routing, a standard library of native modules, and much more.
To create a new Expo project, run the following in your terminal:
npx create-expo-app@latest
Then follow the rest of Expo's getting started guide to start building.
Without a Framework
You can also use React Native without a Framework, however we've found that most developers benefit from one — navigation, native dependencies, and platform tooling are problems the ecosystem has already solved. If a Framework doesn't suit your app, follow Getting Started Without a Framework.
Documentation
The full documentation for React Native can be found on our website.
- Introduction
- Getting Started
- Learn the Basics
- Components and APIs
- UI & Interaction
- Native Modules
- Debugging
- Upgrading
- Architecture
The source for the React Native docs and website is hosted on a separate repository, react/react-native-website.
Contributing
The main purpose of this repository is to continue evolving React Native core. We want to make contributing to this project as easy and transparent as possible, and we are grateful to the community for contributing bug fixes and improvements. Read below to learn how you can take part in improving React Native.
Code of Conduct
Meta has adopted a Code of Conduct that we expect project participants to adhere to. Please read the full text so that you can understand what actions will and will not be tolerated.
Contributing Guide
Read our Contributing Guide to learn about our development process, how to propose bugfixes and improvements, and how to build and test your changes to React Native.
Discussions
Larger discussions and proposals are discussed in react-native-community/discussions-and-proposals.
React Native releases are discussed in reactwg/react-native-releases.
License
React Native is MIT licensed, as found in the LICENSE file.