webraptor / react-native-deck-swiper

tinder like react-native deck swiper
ISC License
137 stars 84 forks source link

Freezes on fast navigating through screens #77

Open therobertgrigorian opened 2 years ago

therobertgrigorian commented 2 years ago

Hi! πŸ‘‹

Firstly, thanks for your work on this project! πŸ™‚

Today I used patch-package to patch react-native-deck-swiper@2.0.5 for the project I'm working on.

If swipe and navigate to another screen and return back to the screen the swiper deck is frozen intermittently. I suppose the root cause is if we do it fast the component can't register an event in time and we trying to remove the event listener that isn't registered yet.

And one more fix - removeEventListener is deprecated and I replaced it with the remove method.

Here is the diff that solved my problem:

diff --git a/node_modules/react-native-deck-swiper/Swiper.js b/node_modules/react-native-deck-swiper/Swiper.js
index edcc140..a122119 100644
--- a/node_modules/react-native-deck-swiper/Swiper.js
+++ b/node_modules/react-native-deck-swiper/Swiper.js
@@ -1,5 +1,5 @@
 import React, { Component } from 'react'
-import { PanResponder, Text, View, Dimensions, Animated } from 'react-native'
+import { PanResponder, Text, View, Dimensions, Animated, InteractionManager } from 'react-native';
 import PropTypes from 'prop-types'
 import isEqual from 'lodash/isEqual'

@@ -56,6 +56,7 @@ class Swiper extends Component {
     this._mounted = true
     this._animatedValueX = 0
     this._animatedValueY = 0
+    this._changeEventSubscription = null;

     this.state.pan.x.addListener(value => (this._animatedValueX = value.value))
     this.state.pan.y.addListener(value => (this._animatedValueY = value.value))
@@ -82,9 +83,11 @@ class Swiper extends Component {

   componentWillUnmount = () => {
     this._mounted = false
-    this.state.pan.x.removeAllListeners()
-    this.state.pan.y.removeAllListeners()
-    Dimensions.removeEventListener('change', this.onDimensionsChange)
+    InteractionManager.runAfterInteractions(() => {
+      this.state.pan.x.removeAllListeners()
+      this.state.pan.y.removeAllListeners()
+      this._changeEventSubscription?.remove()
+    });
   }

   getCardStyle = () => {
@@ -110,7 +113,7 @@ class Swiper extends Component {

   initializeCardStyle = () => {
     // this.forceUpdate()
-    Dimensions.addEventListener('change', this.onDimensionsChange)
+    this._changeEventSubscription = Dimensions.addEventListener('change', this.onDimensionsChange)
   }

   initializePanResponder = () => {

This issue body was partially generated by patch-package.

dakotawalker commented 2 years ago

Upgrading to 2.0.8 didn't resolve the issue but patching with this diff did. Thanks @therobertgrigorian.

webraptor commented 2 years ago

You can open a PR and bump to 2.0.9 with the fix