webraptor / react-native-deck-swiper

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

Getting 'swipeRight' of null [Bug] #115

Closed maheraldous closed 1 year ago

maheraldous commented 1 year ago

Hello I am getting these errors depending on the directions I swipe to. ERROR TypeError: Cannot read property 'swipeRight' of null, js engine: hermes ERROR TypeError: Cannot read property 'swipeLeft' of null, js engine: hermes

The errors dose not occur when swiping but it's appears when I swipe using buttons so something like the code below:

// Data from outside the component
const profiles = [
  { id: '1', name: 'John Doe', age: 25, image: require('../assets/logos/avatar.jpg'), location: 'New York, USA', distance: 500 },
  { id: '2', name: 'Jane Smith', age: 28, image: require('../assets/logos/avatar.png'), location: 'London, UK', distance: 50 },
  { id: '3', name: 'Mike Johnson', age: 30, image: require('../assets/logos/avatar.jpg'), location: 'Paris, France', distance: 100 },
];
// Inside of SwipeScreen.js

  const swipeCardsRef = useRef(null);

  const handleSwipeRight = () => {
    setTimeout(() => {
      if (!isSwiping) {
        setDisableSwipeReturn(true);
        swipeCardsRef.current.swipeRight();
      }
    }, 1000);
  };

  const handleSwipeLeft = () => {
    setTimeout(() => {
      if (!isSwiping) {
        setDisableSwipeReturn(false);
        swipeCardsRef.current.swipeLeft();
      }
    }, 1000);
  };
// Inside of SwipeScreen.js
  return (
    <View style={styles.container}>

      {(!isAllSwiped && profiles) ? (
        <Swiper
          ref={swipeCardsRef}
          cards={profiles}
          renderCard={renderCard}
          // onTapCardDeadZone={20}
          onSwiped={handleCardSwiped}
          onSwipedAll={handleAllSwiped}
          // onSwipedRight={handleSwipeRight}
          // onSwipedLeft={handleSwipeLeft}
          disableBottomSwipe={true}
          disableTopSwipe={true}
          swipeBackCard={true}
          horizontalSwipe={isSwipeable}
          // horizontalThreshold={SCREEN_WIDTH / 4}
          verticalSwipe={isSwipeable}
          // cardIndex={0}
          cardIndex={currentProfileIndex}
          cardVerticalMargin={0}
          cardHorizontalMargin={0}
          backgroundColor={'#000000'}
          stackSize= {3}
          // stackScale={1}
          // stackSeparation={15}
        />
      ) : (
        <StatusCard text="Loading..." />
      )}

     // Like Button
      {!isAllSwiped && (
        <View style={styles.swipeButtonContainerLike}>
          <CustomButton
            onPress={handleSwipeRight}
            iconName={'heart'}
            iconType={'MaterialCommunityIcons'}
            color={'#FFFFFF'}
            size={50}
            // styleButton={{
            //   backgroundColor: 'green',
            // }}
            styleButtonView={{
              backgroundColor: 'rgba(206, 45, 127, 1)',
            }}
          />
        </View>
      )}

      // Dislike Button
      {!isAllSwiped && (
        <View style={styles.swipeButtonContainerDislike}>
          <CustomButton
              onPress={handleSwipeLeft}
              iconName={'heart-remove'}
              iconType={'MaterialCommunityIcons'}
              color={'rgba(206, 45, 127, 1)'}
              size={50}
              styleButtonView={{
                backgroundColor: '#FFFFFF',
              }}
          />
        </View>
      )}

      // Return Button or Go Back
      {(!isAllSwiped || (disableSwipeReturn == false)) && (
        <View style={styles.swipeButtonContainerReturn}>
          <CustomButton
              onPress={handleSwipeReturn}
              disabled={disableSwipeReturn}
              iconName={'rotate-ccw'}
              iconType={'Feather'}
              color={'rgba(206, 45, 127, 1)'}
              size={40}
              styleButtonView={{
                backgroundColor: '#FFFFFF',
              }}
          />
        </View>
      )}

      // A View to show after the cards end
      {isAllSwiped && (
        <View style={styles.allSwipedContainer}>
          <Text>All cards are swiped!</Text>
        </View>
      )}

    </View>
  );

Those errors only appears when I swipe with buttons and very fast but not when I swipe very slow with buttons. I tried to set a timer for 1 seconds and more but no matter how long is the timer, I keep getting those errors when I press the buttons very fast.

I tried to create a clean test without adding so much stuff but the results still the same.

webraptor commented 1 year ago

your swipeCardsRef.current is null when you press the button. the timeout wouldn’t help. make sure your swiper ref is defined when you try to use it and you should be good

maheraldous commented 1 year ago

@webraptor but in the package example it always use swiper ref = null so how should I do what you say.

Can you write your edits to make it easier to understand.

I also getting the same error with Return button since ONLY after the last card swiped when I return it gives null error since there is no more card OR It gives me a loop again where the cards starts over.

So with other word as long as the cards not done I can use the return button as it supposed to be but not after the last card.

maheraldous commented 1 year ago

Fixed it by checking if swipeCardsRef.current nullor not before making an action ith the button

  const handleSwipeRight = () => {
    if (!isSwiping) {
      setDisableSwipeReturn(true);
      if (swipeCardsRef.current) {
        swipeCardsRef.current.swipeRight();
      }
    }
  };

  const handleSwipeLeft = () => {
    if (!isSwiping) {
      setDisableSwipeReturn(false);
      if (swipeCardsRef.current) {
        swipeCardsRef.current.swipeLeft();
      }
    }
  };

  const handleSwipeReturn = () => {
    if (!isSwiping) {
      setDisableSwipeReturn(true);
      if (swipeCardsRef.current) {
        swipeCardsRef.current.swipeBack();
      }
    }
    if (isAllSwiped) {
      setIsAllSwiped(false);
    }
  };