Commit 560d1b5
authored
Fix GestureDetector unresponsive after display:none toggle (New Arch) (#3964)
## Description
On New Architecture, when a parent view has display: 'none' and siblings
change while hidden, the native UIView backing a component may be
recycled and replaced. The React view tag stays the same but the UIView
instance changes, causing gesture recognizers to be lost.
This adds a reattachHandlersIfNeeded check in flushOperations that
re-binds handlers whose native view has changed. The check is a fast
no-op (pointer comparison) when views haven't been recycled.
Fixes #3937
## Test plan
Tested with both v2 (Gesture.Tap()) and v3 (useTapGesture) APIs on iOS
simulator (New Architecture).
Minimal repro to verify the fix:
```ts
import React, { useCallback, useState } from 'react';
import { Button, StyleSheet, Text, View } from 'react-native';
import {
Gesture,
GestureDetector,
useTapGesture,
} from 'react-native-gesture-handler';
export default function DisplayNone() {
const [tapCountV2, setTapCountV2] = useState(0);
const [tapCountV3, setTapCountV3] = useState(0);
const tapV2 = Gesture.Tap()
.runOnJS(true)
.onStart(() => {
setTapCountV2((c) => c + 1);
});
const tapV3 = useTapGesture({
runOnJS: true,
onActivate: () => {
setTapCountV3((c) => c + 1);
},
});
const [visible, setVisible] = useState(true);
const [randomViews, setRandomViews] = useState(100);
const runTest = useCallback(() => {
setVisible(false);
setTimeout(() => {
setRandomViews(Math.random() * 100);
setTimeout(() => {
setVisible(true);
}, 500);
}, 500);
}, []);
return (
<View style={styles.container}>
<Text
style={[
styles.status,
{ color: tapCountV2 > 0 ? 'green' : 'red', fontSize: 24 },
]}>
v2 Tap count: {tapCountV2}
</Text>
<Text
style={[
styles.status,
{ color: tapCountV3 > 0 ? 'green' : 'red', fontSize: 24 },
]}>
v3 Tap count: {tapCountV3}
</Text>
<Button title="Run Test (Hide→Change→Show)" onPress={runTest} />
<View
style={[
styles.wrapper,
{
display: visible ? 'flex' : 'none',
},
]}>
<View style={styles.row}>
{Array.from({ length: randomViews }).map((_, i) => (
<View key={i} style={styles.dot} />
))}
</View>
<View style={styles.boxRow}>
<GestureDetector gesture={tapV2}>
<View style={styles.blueBox}>
<Text style={styles.blueBoxText}>v2</Text>
</View>
</GestureDetector>
<GestureDetector gesture={tapV3}>
<View style={styles.greenBox}>
<Text style={styles.blueBoxText}>v3</Text>
</View>
</GestureDetector>
</View>
</View>
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#ecf0f1',
padding: 8,
},
status: {
fontSize: 16,
fontWeight: 'bold',
marginBottom: 20,
textAlign: 'center',
},
wrapper: {
marginTop: 50,
gap: 20,
backgroundColor: 'yellow',
},
row: {
flexDirection: 'row',
},
dot: {
width: 2,
height: 2,
backgroundColor: 'black',
},
boxRow: {
flexDirection: 'row',
gap: 20,
},
blueBox: {
height: 50,
width: 50,
backgroundColor: 'blue',
justifyContent: 'center',
alignItems: 'center',
},
greenBox: {
height: 50,
width: 50,
backgroundColor: 'green',
justifyContent: 'center',
alignItems: 'center',
},
blueBoxText: {
color: 'white',
fontWeight: 'bold',
},
});
```
Steps:
- Tap the box — count increments
- Press "Hide → Change → Show" to trigger display:none + sibling change
+ show
- Tap again — count should still increment (was broken before this fix)
- Repeat multiple cycles to confirm reliability1 parent 35cb78c commit 560d1b5
7 files changed
Lines changed: 65 additions & 11 deletions
File tree
- packages/react-native-gesture-handler/apple
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
85 | 85 | | |
86 | 86 | | |
87 | 87 | | |
| 88 | + | |
88 | 89 | | |
89 | 90 | | |
90 | 91 | | |
| |||
Lines changed: 3 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
262 | 262 | | |
263 | 263 | | |
264 | 264 | | |
| 265 | + | |
| 266 | + | |
265 | 267 | | |
266 | 268 | | |
267 | 269 | | |
| |||
271 | 273 | | |
272 | 274 | | |
273 | 275 | | |
| 276 | + | |
274 | 277 | | |
275 | 278 | | |
276 | 279 | | |
| |||
Lines changed: 2 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
| 45 | + | |
| 46 | + | |
45 | 47 | | |
Lines changed: 40 additions & 2 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
171 | 171 | | |
172 | 172 | | |
173 | 173 | | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
174 | 189 | | |
175 | 190 | | |
176 | 191 | | |
| |||
181 | 196 | | |
182 | 197 | | |
183 | 198 | | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
184 | 206 | | |
185 | 207 | | |
186 | 208 | | |
187 | 209 | | |
188 | | - | |
189 | | - | |
190 | 210 | | |
191 | 211 | | |
192 | 212 | | |
| |||
224 | 244 | | |
225 | 245 | | |
226 | 246 | | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
227 | 265 | | |
228 | 266 | | |
229 | 267 | | |
| |||
Lines changed: 12 additions & 9 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
171 | 171 | | |
172 | 172 | | |
173 | 173 | | |
174 | | - | |
175 | | - | |
176 | | - | |
177 | | - | |
178 | 174 | | |
179 | | - | |
180 | | - | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
181 | 186 | | |
182 | 187 | | |
183 | | - | |
184 | | - | |
185 | | - | |
| 188 | + | |
186 | 189 | | |
187 | 190 | | |
188 | 191 | | |
| |||
Lines changed: 2 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
21 | 21 | | |
22 | 22 | | |
23 | 23 | | |
| 24 | + | |
| 25 | + | |
24 | 26 | | |
Lines changed: 5 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
22 | 22 | | |
23 | 23 | | |
24 | 24 | | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
25 | 30 | | |
26 | 31 | | |
27 | 32 | | |
| |||
0 commit comments