Skip to content

Changing View's importantForAccessibility prop re-mounts all children recursively #10484

@juhasuni

Description

@juhasuni

Problem Description

Changing View's importantForAccessibility prop causes all children recursively to be re-mounted (unmounted and then mounted again). This in turn may cause serious performance issues.

It seems like the issue is caused by the use of React.Children.map function, which has an un-documented feature where each mapped child gets a new key prop. The map function is being used here:

const childrenWithImportantForAccessibility = children => {

It might be possible to switch from map to using React.Children.forEach instead.

Affected libraries

The issue affects at least the most popular navigation library, React Navigation where the previous screen gets unmounted when you navigate to a new screen.

Specifically the issue happens here:
https://github.com/react-navigation/react-navigation/blob/b28bb2b45ee39a8062020fba667e155c342c6629/packages/stack/src/views/Stack/Card.tsx#L520

The rest object passed as props to View contains importantForAccessibility prop.

Steps To Reproduce

Use the example code to below to reproduce the issue. Clicking the <Button /> causes the <Child /> to be re-mounted.

import React from 'react';
import { View, Button } from 'react-native';

const Container = ({ route, navigation }: Props) => {
  const [value, setValue] = useState<'auto' | 'no-hide-descendants'>('auto');

  return (<View style={{
    flex: 1, alignItems: 'center', justifyContent: 'center'
  }}>
    <View importantForAccessibility={value}><Child /></View>
    <Button title='Toggle' onPress={() => setValue((prev) => prev === 'auto' ? 'no-hide-descendants' : 'auto')} />
  </View >);
};

const Child = () => {
  useEffect(() => {
    return () => { console.log('Child just got unmounted'); };
  }, []);

  return <View />;
};

Expected Results

<Child /> shouldn't be unmounted when the parent's importantForAccessibility prop changes.

CLI version

7.0.4

Environment

System:
    OS: Windows 10 10.0.19044
    CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
    Memory: 20.39 GB / 31.90 GB
  Binaries:
    Node: 16.16.0 - C:\Program Files\nodejs\node.EXE
    Yarn: 1.22.19 - C:\Program Files (x86)\Yarn\bin\yarn.CMD
    npm: 8.11.0 - C:\Program Files\nodejs\npm.CMD
    Watchman: Not Found
  SDKs:
    Android SDK: Not Found
    Windows SDK:
      AllowDevelopmentWithoutDevLicense: Enabled
      Versions: 10.0.18362.0, 10.0.19041.0
  IDEs:
    Android Studio: Not Found
    Visual Studio: 16.11.32802.440 (Visual Studio Community 2019)
  Languages:
    Java: Not Found
  npmPackages:
    @react-native-community/cli: Not Found
    react: Not Found
    react-native: 0.68.2 => 0.68.2
    react-native-windows: 0.68.14 => 0.68.14
  npmGlobalPackages:
    *react-native*: Not Found

Target Platform Version

10.0.19041

Target Device(s)

Desktop

Visual Studio Version

Visual Studio 2019

Build Configuration

Debug

Snack, code example, screenshot, or link to a repository

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions