Skip to content

Commit

Permalink
fix(iOS, Paper): possibility of infinite loop when swiping back in ne…
Browse files Browse the repository at this point in the history
…sted stack (#2223)

## Description

In #2193 I've made a mistake - on Paper, when there is no touch handler
held in `_touchHandler` field I've started
lookup for touch handler in ancestor chain from `self` -> which leads to
infinite loop when swiping back in nested-stack navigation scenario.


## Changes

* Started lookup from superview.


## Test code and steps to reproduce

`Test2223`

1. Navigate to NestedStack.
2. Navigate to NestedStack details screen.
3. Use swipe gesture to go-back


W/o this PR the application will crash hitting infinite loop.

Also test that this behaviour remains fixed:

* #2131

## Checklist

- [x] Included code example that can be used to test this change
- [x] Ensured that CI passes
  • Loading branch information
kkafar authored Jul 2, 2024
1 parent a9bc111 commit e53dcb9
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 1 deletion.
1 change: 1 addition & 0 deletions apps/test-examples/App.js
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@ import Test2048 from './src/Test2048';
import Test2069 from './src/Test2069';
import Test2118 from './src/Test2118';
import Test2184 from './src/Test2184';
import Test2223 from './src/Test2223';
import TestScreenAnimation from './src/TestScreenAnimation';
import TestHeader from './src/TestHeader';

Expand Down
88 changes: 88 additions & 0 deletions apps/test-examples/src/Test2223.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import React from 'react';
import { View, Text, Button, Pressable, StyleSheet, Alert } from 'react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator();
const NestedStack = createNativeStackNavigator();

export default function App() {
return (
<NavigationContainer>
<Stack.Navigator screenOptions={{ animation: 'slide_from_left' }}>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="DetailsStack" component={DetailsScreen} />
<Stack.Screen name="NestedStack" component={NestedStackScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}

function NestedStackScreen() {
return (
<NestedStack.Navigator>
<NestedStack.Screen name="NSHome" component={HomeScreen} />
<NestedStack.Screen name="NSDetailsStack" component={DetailsScreen} />
</NestedStack.Navigator>
);
}

function HomeScreen() {
const navigation = useNavigation();
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('DetailsStack')}
/>
<Button
title="Go to NestedStack"
onPress={() => navigation.navigate('NestedStack')}
/>
<Button
title="Go to NestedStack Details"
onPress={() => navigation.navigate('NSDetailsStack')}
/>
</View>
);
}

function DetailsScreen() {
return (
<View style={{ flex: 1, alignItems: 'center' }}>
{new Array(10).fill(0).map((_, i) => (
<Pressable
key={i.toString()}
onPress={() => {
Alert.alert('Pressed!');
}}
style={({ pressed }) => [
{
backgroundColor: pressed ? 'rgb(210, 230, 255)' : 'white',
},
styles.wrapperCustom,
]}>
{({ pressed }) => (
<Text style={styles.text}>{pressed ? 'Pressed!' : 'Press Me'}</Text>
)}
</Pressable>
))}
</View>
);
}

const styles = StyleSheet.create({
wrapperCustom: {
width: '100%',
height: 100,
marginHorizontal: 30,
borderRadius: 10,
margin: 10,
},
text: {
fontSize: 20,
color: 'black',
},
});

2 changes: 1 addition & 1 deletion ios/utils/UIView+RNSUtility.mm
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ @implementation UIView (RNSUtility)

- (nullable RNS_TOUCH_HANDLER_ARCH_TYPE *)rnscreens_findTouchHandlerInAncestorChain
{
UIView *parent = self;
UIView *parent = self.superview;

#ifdef RCT_NEW_ARCH_ENABLED
// On Fabric there is no view that exposes touchHandler above us in the view hierarchy, however it is still
Expand Down

0 comments on commit e53dcb9

Please sign in to comment.