react / react/react-strict-dom

Provide a way to avoid/solve React Native view flattening issues

Open
#319 9 comments 1 reaction 0 assignees View on GitHub

Nobody has claimed this yet.

bug: react-native
Dominant language
JavaScript
Stars
3.6k
Forks
206
PR merge metrics
No merged PRs in 30d

Description

Describe the feature request

This is a follow-up to #318 regarding the nativeProps feature request, in which @necolas raised a specific issue related to view flattening and the collapsable prop.

Brief Summary
  • By default, React Native performs view flattening on both iOS and Android. This process removes "layout-only" views from the platform view tree to reduce the number of platform views created. In contrast, the web does not have a corresponding technique, as the DOM element tree is preserved as rendered.
  • Layout-only views are views that handle layout-related properties like margins, padding, etc., which can be managed by Yoga and safely removed. However, views with properties like background color, opacity, borders, shadows, etc., cannot be flattened because these properties cannot be replaced by pure Yoga layout adjustments.
  • View flattening distorts the platform view tree, both statically (by making views that were previously separate into siblings) and dynamically (when a view, along with all its children, transitions between being "layout-only" and an actual view).
Example of issues caused by view flattening
  1. Screen reader focus order: On iOS, the screen reader considers platform view grouping, reading text elements under the same parent view consecutively. With view flattening, views from different flattened containers can end up in the same container, resulting in an incorrect screen reader order (this is the issue I am currently facing).
  2. Validation error styling: For example, setting a red border or background around a view containing a text input to signal a validation error can cause the container view to change from "layout-only" to an actual view. This, in turn, can trigger the platform text input component to be recreated, resetting its intrinsic native state (e.g., cursor position). More details here.
  3. Community libraries: Libraries like React Native Gesture Handler sometimes need to attach to an actual native view. With view flattening, the required view might be removed, causing errors.

These are just a few examples of how view flattening can lead to unexpected and hard-to-diagnose issues, as it’s not always obvious which views are being removed.

Traditionally, the standard way to disable view flattening is by using the collapsable prop, which explicitly clarifies the developer's intent. However, this prop is not accessible in RSD. The proposal for nativeProps was intended to create an escape hatch to allow access to this or other similar props.

Potential solutions
  1. Disable view flattening in RSD altogether: This would align React Native's behavior with the DOM, where platform views are never flattened. However, this is a crude solution that would eliminate a generally useful optimization technique and could have performance implications.
  2. Encourage users to use React Native's View instead of h.div, etc.: While possible, this approach requires users to maintain two sets of styles, RSD styles and React Native styles, which is a significant inconvenience.
  3. Use another prop that disables view flattening as a side effect: For example, the nativeID prop (which RSD maps from id) could be used. However, this approach lacks clarity of intent, and a future developer (or even our future selves) might mistakenly remove it, thinking the ID is unused.

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reading the linked #318 discussion, the React Native collapsable and view-flattening documentation, and the RSD usage of h.div and nativeProps described here. Compare the proposed approaches with the screen-reader, validation, and community-library cases; the issue is complete only after maintainers agree on a specific API or behavior and its documented scope.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, react-native
Domain
accessibility, frontend, mobile-dev
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.