Tiger_Stripes
Tiger_Stripes

Reputation: 525

State doesn't seem to update within Animated.spring()

I am trying to make a tinder like swipe functionality using a functional component.

I've essentially made a functional version of the below tutorial

https://www.instamobile.io/react-native-controls/react-native-swipe-cards-tinder/

However I am having a weird issue where it would appear the state of the card to display doesn't get updated properly. The first time it seems to work but from then on wards it always seems to return 0

I've made a video to illustrate the weird behaviour

https://youtu.be/CRSH36FdhlY

 import React, {useState, useEffect, useRef} from "react";
import { StyleSheet, View, Text, TouchableOpacity, Image, ImageBackground,  Animated, PanResponder,Dimensions  } from "react-native";
import { LinearGradient } from 'expo-linear-gradient';
import { StatusBar } from 'expo-status-bar';
import QuestionBox from "../Components/questionBox.js"

import {styles} from "./questionStyles.js"


const SCREEN_HEIGHT = Dimensions.get('window').height
const SCREEN_WIDTH = Dimensions.get('window').width

function QuestionScreen({route, navigation}) {
    
     const {players, mode} = route.params;
     
     const [questions, setQuestions]=useState([
     
     {title:"Dare", text:"boooooooooooo"},
     {title:"Question", text:"fdoooooo"},
     {title:"Question", text:"fdfsfsfsfsfsfsoooooo"},
     {title:"Dare", text:"bodfooo"}


     ]);

    
     const pan = useRef(new Animated.ValueXY()).current;
     const [currentIndex, setIndex] =useState(0);
     const [times, setTimes]=useState(0)
     
      
 const panResponder = useRef(
    PanResponder.create({
      onMoveShouldSetPanResponder: (evt, gestureState) => true,
      
      onPanResponderMove: Animated.event([null, { dx: pan.x, dy: pan.y }],{useNativeDriver: false}) ,

       onPanResponderRelease: (evt, gestureState) => {
       pan.flattenOffset();
      },
      onPanResponderRelease: (evt, gestureState) => {
    
        if (gestureState.dx > 120 ) {
        
          Animated.spring(pan, {
          
            toValue: { x: SCREEN_WIDTH + 100, y: gestureState.dy },
            useNativeDriver: true
          }).start(()=>{
          setIndex(currentIndex+1)
        pan.setValue({ x: 0, y: 0 })
        console.log("value of current index is: ".concat(currentIndex) )
        
          })
          
        } 
        
        else {
    Animated.spring(pan, {
       toValue: { x: 0, y: 0 },
       useNativeDriver: true,
       friction: 4
       }).start()
    }
          }
          
                  
    })
  ).current;

 const rotate = pan.x.interpolate({
    inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
    outputRange: ['-10deg', '0deg', '10deg'],
    extrapolate: 'clamp'
})
    const rotateAndTranslate= {
    transform:  [{rotate:rotate},{ translateX: pan.x }, { translateY: pan.y }]
        }

    const nextOpacity = pan.x.interpolate({
   inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
   outputRange: [0, 0, 1],
   extrapolate: 'clamp'
})

const nextCardOpacity = pan.x.interpolate({
   inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
   outputRange: [1, 0, 1],
   extrapolate: 'clamp'
})
const nextCardScale = pan.x.interpolate({
   inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
   outputRange: [1, 0.8, 1],
   extrapolate: 'clamp'
})   
     
    

const renderQuestions = () => {
   return questions.map((item, i) => {
  if (i < currentIndex) {
  return null
     } else if (i === currentIndex) {
    
     
      return (
        <Animated.View
        key={i}
          style={[rotateAndTranslate,{
                  
            height: "100%",
            width: "100%",
            flex:1    ,
        zIndex:1000,
         elevation:10,
            position:"absolute",
            flexDirection:"column"}]}
            {...panResponder.panHandlers}
        >
        <Animated.View
      style={{
        transform: [{ rotate: "20deg" }],
        position: "absolute",
        top: 20,
        right: 20,
        zIndex: 1000,
        elevation:100,
        opacity:nextOpacity
      }}
    >
      <Text
        style={{
          borderWidth: 1,
          borderColor: "#dd3fac",
          color: "#dd3fac",
          fontSize: 32,
          fontWeight: "800",
          padding: 10
        }}
      >
        NEXT >>
      </Text>
    </Animated.View>


          <QuestionBox title={item.title} text={item.text}  />
        </Animated.View>
      );

      }else {
     
       return (
        <Animated.View
        key={i}
          style={{
          
            height: "100%",
            width: "100%",
            flex:1    ,
            position:"absolute",
            flexDirection:"column",
            opacity: nextCardOpacity,
    transform: [{ scale: nextCardScale }]
    
    }}
            
        >
          <QuestionBox title={item.title} text={item.text}  />
        </Animated.View>
      );


      }
   }).reverse();
};


  
    
 return(
 <>
 <StatusBar   
       translucent={true} />  
       <ImageBackground source={vertBackground} style={styles.image}/>
    
 <View style={styles.container}>

    

    <View style={styles.spacer1} />
    
    <View style={{flex:4.6, width:"100%", height:"100%"}}>
    {renderQuestions()}
    </View>

    <View style={styles.spacer1} / >
    
    
    
   </View>
   </>
  );
}


export default QuestionScreen;

Upvotes: 0

Views: 136

Answers (1)

Stepan Nikulenko
Stepan Nikulenko

Reputation: 653

Try set the index like this:

setIndex(currentIndexValue => currentIndexValue+1);

Upvotes: 1

Related Questions