Skip to content

Commit a3256d4

Browse files
committed
detach handlers
1 parent 8c03f58 commit a3256d4

File tree

2 files changed

+65
-23
lines changed

2 files changed

+65
-23
lines changed

packages/react-native-gesture-handler/apple/RNGestureHandlerDetector.mm

Lines changed: 25 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ - (void)willMoveToWindow:(RNGHWindow *)newWindow
6969
NSNumber *handlerTag = [NSNumber numberWithInt:handler];
7070
[handlerManager.registry detachHandlerWithTag:handlerTag];
7171
}
72+
for (const auto &child : logicChildren) {
73+
for (id handlerTag : child.second.attachedHandlers) {
74+
[handlerManager.registry detachHandlerWithTag:handlerTag];
75+
}
76+
}
77+
logicChildren.clear();
7278
}
7379
}
7480

@@ -227,19 +233,25 @@ - (void)updateProps:(const Props::Shared &)propsBase oldProps:(const Props::Shar
227233
attachedHandlers:_attachedHandlers
228234
nativeHandlers:_nativeHandlers];
229235
[super updateProps:propsBase oldProps:oldPropsBase];
236+
RNGestureHandlerManager *handlerManager = [RNGestureHandlerModule handlerManagerForModuleId:_moduleId];
237+
react_native_assert(handlerManager != nullptr && "Tried to access a non-existent handler manager")
238+
239+
std::unordered_map<int, bool>
240+
shouldKeepLogicChild;
241+
for (const std::pair<const int, LogicChild> &child : logicChildren) {
242+
shouldKeepLogicChild[child.first] = false;
243+
}
230244

231245
for (const RNGestureHandlerDetectorLogicChildrenStruct &child : newProps.logicChildren) {
232246
if (logicChildren.find(child.viewTag) == logicChildren.end()) {
233247
// Initialize the vector for a new logic child
234-
RNGestureHandlerManager *handlerManager = [RNGestureHandlerModule handlerManagerForModuleId:_moduleId];
235-
react_native_assert(handlerManager != nullptr && "Tried to access a non-existent handler manager")
236-
logicChildren[child.viewTag]
237-
.view = [handlerManager viewForReactTag:@(child.viewTag)];
248+
logicChildren[child.viewTag].view = [handlerManager viewForReactTag:@(child.viewTag)];
238249
logicChildren[child.viewTag].handlerTags = {};
239250
logicChildren[child.viewTag].attachedHandlers = [NSMutableSet set];
240251
logicChildren[child.viewTag].nativeHandlers = [NSMutableSet set];
241252
[[handlerManager registry] registerLogicChild:@(child.viewTag) toParent:@(self.tag)];
242253
}
254+
shouldKeepLogicChild[child.viewTag] = true;
243255
[self updatePropsInternal:child.handlerTags
244256
oldHandlerTags:logicChildren[child.viewTag].handlerTags
245257
isLogic:true
@@ -248,6 +260,15 @@ - (void)updateProps:(const Props::Shared &)propsBase oldProps:(const Props::Shar
248260
nativeHandlers:logicChildren[child.viewTag].nativeHandlers];
249261
}
250262

263+
for (const auto &child : shouldKeepLogicChild) {
264+
if (!child.second) {
265+
for (id handlerTag : logicChildren[child.first].attachedHandlers) {
266+
[handlerManager.registry detachHandlerWithTag:handlerTag];
267+
}
268+
logicChildren.erase(child.first);
269+
}
270+
}
271+
251272
// Override to force hittesting to work outside bounds
252273
self.clipsToBounds = NO;
253274
}

packages/react-native-gesture-handler/src/v3/HostGestureDetector.web.tsx

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const HostGestureDetector = (props: GestureHandlerDetectorProps) => {
2525
const attachedHandlerTags = useRef<Set<number>>(new Set<number>());
2626
const attachedNativeHandlerTags = useRef<Set<number>>(new Set<number>());
2727

28-
const logicChildren = useRef<Map<LogicDetectorProps, LogicChild>>(new Map());
28+
const logicChildren = useRef<Map<number, LogicChild>>(new Map());
2929

3030
const detachHandlers = (
3131
oldHandlerTags: Set<number>,
@@ -103,18 +103,29 @@ const HostGestureDetector = (props: GestureHandlerDetectorProps) => {
103103
attachedHandlerTags.current,
104104
attachedNativeHandlerTags.current
105105
);
106+
}, [handlerTags, children]);
107+
108+
useEffect(() => {
109+
const shouldKeepLogicChild: Map<number, boolean> = new Map();
106110

107-
props.logicChildren?.forEach((child) => {
108-
if (!logicChildren.current.has(child)) {
109-
logicChildren.current.set(child, {
111+
for (const key of logicChildren.current.keys()) {
112+
shouldKeepLogicChild.set(key, false);
113+
}
114+
115+
props.logicChildren?.forEach((child, key) => {
116+
if (!logicChildren.current.has(child.viewTag)) {
117+
logicChildren.current.set(child.viewTag, {
110118
attachedHandlerTags: new Set(),
111119
attachedNativeHandlerTags: new Set(),
112120
});
113121
}
114-
const attachedHandlerTags =
115-
logicChildren.current.get(child)?.attachedHandlerTags;
116-
const attachedNativeHandlerTags =
117-
logicChildren.current.get(child)?.attachedNativeHandlerTags;
122+
shouldKeepLogicChild.set(key.viewTag, true);
123+
const attachedHandlerTags = logicChildren.current.get(
124+
child.viewTag
125+
)?.attachedHandlerTags;
126+
const attachedNativeHandlerTags = logicChildren.current.get(
127+
child.viewTag
128+
)?.attachedNativeHandlerTags;
118129
if (attachedHandlerTags && attachedNativeHandlerTags) {
119130
attachHandlers(
120131
child.viewRef,
@@ -126,27 +137,37 @@ const HostGestureDetector = (props: GestureHandlerDetectorProps) => {
126137
);
127138
}
128139
});
129-
}, [handlerTags, children]);
130140

131-
useEffect(() => {
132-
return () => {
133-
detachHandlers(
134-
attachedHandlerTags.current,
135-
attachedHandlerTags.current,
136-
attachedNativeHandlerTags.current
137-
);
138-
props.logicChildren?.forEach((child) => {
141+
shouldKeepLogicChild.forEach((value, key) => {
142+
if (value) {
139143
const attachedHandlerTags =
140-
logicChildren.current.get(child)?.attachedHandlerTags;
144+
logicChildren.current.get(key)?.attachedHandlerTags;
141145
const attachedNativeHandlerTags =
142-
logicChildren.current.get(child)?.attachedNativeHandlerTags;
146+
logicChildren.current.get(key)?.attachedNativeHandlerTags;
143147
if (attachedHandlerTags && attachedNativeHandlerTags) {
144148
detachHandlers(
145149
attachedHandlerTags,
146150
attachedHandlerTags,
147151
attachedNativeHandlerTags
148152
);
149153
}
154+
}
155+
});
156+
}, [props.logicChildren]);
157+
158+
useEffect(() => {
159+
return () => {
160+
detachHandlers(
161+
attachedHandlerTags.current,
162+
attachedHandlerTags.current,
163+
attachedNativeHandlerTags.current
164+
);
165+
logicChildren?.current.forEach((child) => {
166+
detachHandlers(
167+
child.attachedHandlerTags,
168+
child.attachedHandlerTags,
169+
child.attachedNativeHandlerTags
170+
);
150171
});
151172
};
152173
}, []);

0 commit comments

Comments
 (0)