From 5c8e4c229047598e44b1c03ccbeb86b8ae65db33 Mon Sep 17 00:00:00 2001 From: Kyle Date: Tue, 26 Sep 2023 08:48:48 +0300 Subject: [PATCH 1/5] [fix] matchMedia memory leak --- packages/emoji-mart/src/components/Picker/Picker.tsx | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/emoji-mart/src/components/Picker/Picker.tsx b/packages/emoji-mart/src/components/Picker/Picker.tsx index cced465b..aa7c5884 100644 --- a/packages/emoji-mart/src/components/Picker/Picker.tsx +++ b/packages/emoji-mart/src/components/Picker/Picker.tsx @@ -106,6 +106,7 @@ export default class Picker extends Component { componentWillUnmount() { this.unregister() + this.darkMedia?.removeEventListener(this.darkMediaCallback); } async reset(nextState = {}) { @@ -194,6 +195,11 @@ export default class Picker extends Component { } } + darkMediaCallback = () => { + if (this.props.theme != 'auto') return + this.setState({ theme: this.darkMedia.matches ? 'dark' : 'light' }) + } + initTheme(theme) { if (theme != 'auto') return theme @@ -201,10 +207,7 @@ export default class Picker extends Component { this.darkMedia = matchMedia('(prefers-color-scheme: dark)') if (this.darkMedia.media.match(/^not/)) return 'light' - this.darkMedia.addListener(() => { - if (this.props.theme != 'auto') return - this.setState({ theme: this.darkMedia.matches ? 'dark' : 'light' }) - }) + this.darkMedia.addListener(this.darkMediaCallback); } return this.darkMedia.matches ? 'dark' : 'light' From 8fd3b3379b2e5a9af58cd418ab0ed78842fb568e Mon Sep 17 00:00:00 2001 From: Kyle Date: Tue, 26 Sep 2023 08:52:23 +0300 Subject: [PATCH 2/5] [fix] matchMedia memory leak --- packages/emoji-mart/src/components/Picker/Picker.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/emoji-mart/src/components/Picker/Picker.tsx b/packages/emoji-mart/src/components/Picker/Picker.tsx index aa7c5884..bd96e811 100644 --- a/packages/emoji-mart/src/components/Picker/Picker.tsx +++ b/packages/emoji-mart/src/components/Picker/Picker.tsx @@ -106,7 +106,7 @@ export default class Picker extends Component { componentWillUnmount() { this.unregister() - this.darkMedia?.removeEventListener(this.darkMediaCallback); + this.darkMedia?.removeListener(this.darkMediaCallback); } async reset(nextState = {}) { From cda05caefdbe86a804866adb1bd5ef1b7b1741e1 Mon Sep 17 00:00:00 2001 From: Kyle Date: Wed, 27 Sep 2023 06:45:02 +0300 Subject: [PATCH 3/5] prettier:fix --- packages/emoji-mart/src/components/Picker/Picker.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/emoji-mart/src/components/Picker/Picker.tsx b/packages/emoji-mart/src/components/Picker/Picker.tsx index bd96e811..692b0fb9 100644 --- a/packages/emoji-mart/src/components/Picker/Picker.tsx +++ b/packages/emoji-mart/src/components/Picker/Picker.tsx @@ -106,7 +106,7 @@ export default class Picker extends Component { componentWillUnmount() { this.unregister() - this.darkMedia?.removeListener(this.darkMediaCallback); + this.darkMedia?.removeListener(this.darkMediaCallback) } async reset(nextState = {}) { @@ -207,7 +207,7 @@ export default class Picker extends Component { this.darkMedia = matchMedia('(prefers-color-scheme: dark)') if (this.darkMedia.media.match(/^not/)) return 'light' - this.darkMedia.addListener(this.darkMediaCallback); + this.darkMedia.addListener(this.darkMediaCallback) } return this.darkMedia.matches ? 'dark' : 'light' From 96eb041b99e277cf7c9da29012c8edfd562efacf Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Sat, 6 Jan 2024 15:27:36 -0500 Subject: [PATCH 4/5] =?UTF-8?q?Move=20removeListener=20to=20unregister=20S?= =?UTF-8?q?o=20that=20it=E2=80=99s=20properly=20called=20when=20the=20DOMN?= =?UTF-8?q?ode=20is=20removed=20from=20the=20DOM?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/emoji-mart/src/components/Picker/Picker.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/emoji-mart/src/components/Picker/Picker.tsx b/packages/emoji-mart/src/components/Picker/Picker.tsx index 692b0fb9..e35717f3 100644 --- a/packages/emoji-mart/src/components/Picker/Picker.tsx +++ b/packages/emoji-mart/src/components/Picker/Picker.tsx @@ -106,7 +106,6 @@ export default class Picker extends Component { componentWillUnmount() { this.unregister() - this.darkMedia?.removeListener(this.darkMediaCallback) } async reset(nextState = {}) { @@ -128,6 +127,7 @@ export default class Picker extends Component { unregister() { document.removeEventListener('click', this.handleClickOutside) + this.darkMedia?.removeListener(this.darkMediaCallback) this.unobserve() } From 17553dce844121baab35d253cbb3fbb78f67b1be Mon Sep 17 00:00:00 2001 From: Etienne Lemay Date: Sat, 6 Jan 2024 15:30:26 -0500 Subject: [PATCH 5/5] Use `addEventListener` instead of `addListener` See https://developer.mozilla.org/en-US/docs/Web/API/MediaQueryList#instance_methods --- packages/emoji-mart/src/components/Picker/Picker.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/emoji-mart/src/components/Picker/Picker.tsx b/packages/emoji-mart/src/components/Picker/Picker.tsx index e35717f3..24cad2e6 100644 --- a/packages/emoji-mart/src/components/Picker/Picker.tsx +++ b/packages/emoji-mart/src/components/Picker/Picker.tsx @@ -127,7 +127,7 @@ export default class Picker extends Component { unregister() { document.removeEventListener('click', this.handleClickOutside) - this.darkMedia?.removeListener(this.darkMediaCallback) + this.darkMedia?.removeEventListener('change', this.darkMediaCallback) this.unobserve() } @@ -207,7 +207,7 @@ export default class Picker extends Component { this.darkMedia = matchMedia('(prefers-color-scheme: dark)') if (this.darkMedia.media.match(/^not/)) return 'light' - this.darkMedia.addListener(this.darkMediaCallback) + this.darkMedia.addEventListener('change', this.darkMediaCallback) } return this.darkMedia.matches ? 'dark' : 'light'