From 0e4363979631e0d9903dd53123bbc3557bf470a4 Mon Sep 17 00:00:00 2001 From: Patrick Kenny Date: Sat, 1 Aug 2026 09:05:37 +0900 Subject: [PATCH] fix unmount race in refresher --- core/src/components/refresher/refresher.tsx | 28 ++++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/core/src/components/refresher/refresher.tsx b/core/src/components/refresher/refresher.tsx index 9d7c6a7ad06..bbb9ced82be 100644 --- a/core/src/components/refresher/refresher.tsx +++ b/core/src/components/refresher/refresher.tsx @@ -299,8 +299,18 @@ export class Refresher implements ComponentInterface { this.scrollEl!.addEventListener('scroll', this.scrollListenerCallback); - this.gesture = (await import('../../utils/gesture')).createGesture({ - el: this.scrollEl!, + const { createGesture } = await import('../../utils/gesture'); + + /** + * The dynamic import createGesture yields to the event loop, so the refresher may + * be disconnected if the component unmounts while it resolves. + */ + if (!this.scrollEl) { + return; + } + + this.gesture = createGesture({ + el: this.scrollEl, gestureName: 'refresher', gesturePriority: 31, direction: 'y', @@ -369,8 +379,18 @@ export class Refresher implements ComponentInterface { }); } - this.gesture = (await import('../../utils/gesture')).createGesture({ - el: this.scrollEl!, + const { createGesture } = await import('../../utils/gesture'); + + /** + * The dynamic import createGesture yields to the event loop, so the refresher may + * be disconnected if the component unmounts while it resolves. + */ + if (!this.scrollEl) { + return; + } + + this.gesture = createGesture({ + el: this.scrollEl, gestureName: 'refresher', gesturePriority: 31, direction: 'y',