react-native icon indicating copy to clipboard operation
react-native copied to clipboard

Pressable gets stuck under the new architecture

Open xdmx opened this issue 1 year ago • 13 comments

Description

I've noticed that using the new architecture under a brand new app (expo app) the pressable button gets stuck. The example is from the Pressable documentation, with a minor change on how it shows the components. Disabling the new architecture it works as expected Using a Pixel_3a_API_34_extension_level_7_x86_64 emulator

Steps to reproduce

  1. npx create-expo-app@latest -e with-new-arch
import React, {useState} from 'react';
import {Pressable, StyleSheet, Text, View} from 'react-native';

const App = () => {
  const [timesPressed, setTimesPressed] = useState(0);

  let textLog = '';
  if (timesPressed > 1) {
    textLog = timesPressed + 'x onPress';
  } else if (timesPressed > 0) {
    textLog = 'onPress';
  }

  return (
    <View style={styles.container}>
      <Pressable
        onPress={() => {
          setTimesPressed(current => current + 1);
        }}
        style={({pressed}) => [
          {
            backgroundColor: pressed ? 'rgb(210, 230, 255)' : 'white',
          },
          styles.wrapperCustom,
        ]}>
        {({pressed}) => (
          <>
            {pressed && <Text style={styles.text}>Pressed!</Text>}
            {!pressed && <Text style={styles.text}>Press Me</Text>}
          </>
        )}
      </Pressable>
      <View style={styles.logBox}>
        <Text testID="pressable_press_console">{textLog}</Text>
      </View>
    </View>
  );
};

const styles = StyleSheet.create({
  container: {
    flex: 1,
    justifyContent: 'center',
  },
  text: {
    fontSize: 16,
  },
  wrapperCustom: {
    borderRadius: 8,
    padding: 6,
  },
  logBox: {
    padding: 20,
    margin: 10,
    borderWidth: StyleSheet.hairlineWidth,
    borderColor: '#f0f0f0',
    backgroundColor: '#f9f9f9',
  },
});

export default App;

React Native Version

0.74.1

Affected Platforms

Runtime - Android

Output of npx react-native info

info Fetching system and libraries information...
System:
  OS: Linux 6.8 Arch Linux
  CPU: (16) x64 AMD Ryzen 7 PRO 4750U with Radeon Graphics
  Memory: 7.84 GB / 29.11 GB
  Shell:
    version: "5.9"
    path: /bin/zsh
Binaries:
  Node:
    version: 20.11.0
    path: ~/.nodenv/versions/20.11.0/bin/node
  Yarn:
    version: 1.22.22
    path: /usr/bin/yarn
  npm:
    version: 10.2.4
    path: ~/.nodenv/versions/20.11.0/bin/npm
  Watchman:
    version: 20240414.112832.0
    path: /usr/bin/watchman
SDKs:
  Android SDK: Not Found
IDEs:
  Android Studio: AI-232.10300.40.2321.11668458
Languages:
  Java:
    version: 17.0.11
    path: /usr/bin/javac
  Ruby:
    version: 3.3.0
    path: /home/user/.rbenv/shims/ruby
npmPackages:
  "@react-native-community/cli": Not Found
  react:
    installed: 18.2.0
    wanted: 18.2.0
  react-native:
    installed: 0.74.1
    wanted: 0.74.1
npmGlobalPackages:
  "*react-native*": Not Found
Android:
  hermesEnabled: true
  newArchEnabled: true
iOS:
  hermesEnabled: Not found
  newArchEnabled: Not found



### Stacktrace or Logs

```text
N/A

Reproducer

https://gist.github.com/xdmx/483cb093f59c23b1dee57b8b64c63696

https://github.com/xdmx/rn-pressable-bug

Screenshots and Videos

No response

xdmx avatar May 19 '24 20:05 xdmx

https://github.com/xdmx/rn-pressable-bug

xdmx avatar May 19 '24 21:05 xdmx

Thanks for opening this @xdmx, we'll be looking into it in the next future

cortinico avatar May 20 '24 10:05 cortinico

This same issue is already reported at multiple places, here are these two references https://github.com/facebook/react-native/issues/36710 https://github.com/facebook/react-native/issues/44643

HarshitMadhav avatar Jun 06 '24 10:06 HarshitMadhav

@xdmx I've started looking into this. I'm wondering if the issue happens only on Expo. Can we create the same repro in a bare React Native App (ideally by using https://github.com/react-native-community/reproducer-react-native)

cortinico avatar Jun 12 '24 15:06 cortinico

I am having this issue (managed Expo app with new architecture enabled, on both Android and iOS is happening). It seems like onPressOut and onPress are not getting fired consecutively (or at least reliably) after onPressIn (it is almost like onPressIn is getting fired repeatedly instead of the Pressable lifecycle continuing to the other events). Unfortunately, I got several commits down the road before I realized that this was happening, so I am not inclined to roll back, but to tell our users to kill and restart the app (because once a Pressable item gets "stuck," the entire app interface freezes). This is sporadic (occurs reliably on some but not all components using Pressable), so I understand how difficult this will be to test...

gtwilliams03 avatar Jun 13 '24 13:06 gtwilliams03

Hey all, I've continued investigating here, and the issue is related to Pressable itself and is unrelated to Expo.

Reproducer for React Native Community CLI app that uses no libraries at all is here: https://github.com/reprodu/cer-react-native-44610

Also the issue is more evident on Android Physical devices as is more likely the onPressIn is followed by a finger movement. It can be reproduced on emulators if you click, move the cursor, and release the mouse.

cortinico avatar Jun 14 '24 15:06 cortinico

@cortinico Does this also fix this issue: #44643 ?

DrZoidberg09 avatar Jun 16 '24 15:06 DrZoidberg09

@cortinico Does this also fix this issue: #44643 ?

Yes those two are duplicates essentially

cortinico avatar Jun 17 '24 10:06 cortinico

Nice, thank you! I wasnt quite sure when I opened the issue as it similar yet a little different. Looking very much forward to a fix!

DrZoidberg09 avatar Jun 17 '24 10:06 DrZoidberg09

Adding another datapoint as I'm investigating. This definitely fixes the issue:

      <Pressable
        onPress={() => {
          setTimesPressed(current => current + 1);
        }}
        style={({pressed}) => [
          {
            backgroundColor: pressed ? 'rgb(210, 230, 255)' : 'white',
          },
          styles.wrapperCustom,
        ]}>
+       <Text>Press Me</Text>
-       {({pressed}) => (
-         <>
-           {pressed && <Text style={styles.text}>Pressed!</Text>}
-           {!pressed && <Text style={styles.text}>Press Me</Text>}
-         </>
-       )}
      </Pressable>

as the problem seems related to scenarios where Pressable have dynamic child.

This also fixes the issue:

      <Pressable
        onPress={() => {
          setTimesPressed(current => current + 1);
        }}
        style={({pressed}) => [
          {
            backgroundColor: pressed ? 'rgb(210, 230, 255)' : 'white',
          },
          styles.wrapperCustom,
        ]}>
        {({pressed}) => (
          <>
+           {pressed && <Text key="1" style={styles.text}>Pressed!</Text>}
+           {!pressed && <Text key="1" style={styles.text}>Press Me</Text>}
-           {pressed && <Text style={styles.text}>Pressed!</Text>}
-           {!pressed && <Text style={styles.text}>Press Me</Text>}
          </>
       )}
      </Pressable>

as there seems to be something going on with react reconciliation. Surprisingly this doens't happen on iOS

cortinico avatar Jun 19 '24 18:06 cortinico

The issue described in #44643 is happening with plain pressable - no dynamic child (as shown in the reproducer). If the thing you described above fixes the issue, then these two issues are not related.

DrZoidberg09 avatar Jun 19 '24 18:06 DrZoidberg09

The issue described in #44643 is happening with plain pressable - no dynamic child (as shown in the reproducer). If the thing you described above fixes the issue, then these two issues are not related.

Cool thanks for the heads up. Then we might have two separate issues. We'll look into this one first and get back to the other

cortinico avatar Jun 19 '24 19:06 cortinico

Just FYI - I was having the "stuck" Pressable issue as described above (where tapping a Pressable item would not complete and the screen would freeze) - upgraded to react-native 0.74.3 yesterday and now the "stuck" Pressable items cause the app to crash when tapped. So, something different, but likely worse.

On Android, tapping a Pressable item causes the app to revert to the splash screen and freeze. On iOS the app simply crashes.

gtwilliams03 avatar Jul 09 '24 13:07 gtwilliams03

Just a heads up that we found the root cause of this issue and we're discussing a couple of potential fixes. See:

  • https://github.com/facebook/react-native/pull/45865

cortinico avatar Aug 01 '24 16:08 cortinico

Thank you all for your patience.

The issue was caused by the event emitter getting destroyed when the view was going off-screen. This PR should fix it and will be shipped in 0.76:

  • https://github.com/facebook/react-native/pull/45865

cortinico avatar Aug 08 '24 16:08 cortinico

感谢大家的耐心。

该问题是由于视图离开屏幕时事件发送器被破坏而引起的。 此 PR 应该可以修复该问题,安装在 0.76 中发布:

@cortinico OK, may I ask if this fix fixes your problem?:https://github.com/facebook/react-native/issues/36710

peaktan avatar Dec 24 '24 15:12 peaktan