Creating A Swipeable Card In React Native (part 2/3)
Tags: reactnative, tutorial, javascript, animation
Published: 2021-08-02 17:03:21

![Gif of Swiping App](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/fshhzb9rqith19bpx3vy.gif)

Continuing from the previous part, I will show you how we can display the next profile picture behind the current profile, add functionality to complete a swipe so that the next profile changes place with the current profile, and also add a reset animation so after an uncompleted swipe the current profile card's position will be elegantly reset.

To start with, let's add state to keep track of the next profile.
```js
export default function App() {
  const [profile,setProfile] = useState(profiles[0])
  const [nextProfile, setNextProfile] = useState(profiles[1])
```
Then, we can add a new View to our inside our return statement to render the new profile. So far, this is what our component returns:
```js
return (
    <SafeAreaView style={styles.container}>
      <View style={styles.cardContainer}>
        <View style={styles.card}>
            <Image source={{uri: nextProfile.pic}} style={{height:"80%",width:"100%"}}></Image>
            <View style={{flex:1,alignContent:'center',justifyContent:'center'}}>
              <Text style={{fontSize:20,fontWeight:"700"}}>{nextProfile.name}</Text>
              <Text>Age: {nextProfile.age}</Text>
              <Text>Likes: {nextProfile.likes.join(', ')}</Text>
            </View>
        </View>
        <PanGestureHandler onGestureEvent={handlePan} onHandlerStateChange={handlePanStateChange}>
          <Animated.View style={[styles.card, {transform:[{translateX},{translateY},{rotate}]}]}>
            <Image source={{uri: profile.pic}} style={{height:"80%",width:"100%"}}></Image>
            <View style={{flex:1,alignContent:'center',justifyContent:'center'}}>
              <Text style={{fontSize:20,fontWeight:"700"}}>{profile.name}</Text>
              <Text>Age: {profile.age}</Text>
              <Text>Likes: {profile.likes.join(', ')}</Text>
            </View>
          </Animated.View>
        </PanGestureHandler>
      </View>
      <StatusBar style="auto" />
    </SafeAreaView>
  );
}
```
Because we have the position style property set to 'absolute' for the cards the cards will overlap with the last one returned being rendered on top.

To make it so swiping will remove the current profile and set nextProfile to the front we will create a method to pass to the onHandlerStateChange prop for our PanGestureHandler. This method will take the nativeEvent as an argument and use it to determine if the current profile has been swiped far enough to qualify as a completed swipe, and if it has then execute the code for swiping.
```js
  const handlePanStateChange = ({nativeEvent}) =>{
    const {state, translationX} = nativeEvent
    if(state === 5){ //When the user takes their finger off the screen
      if(translationX > 185 || translationX < -185){
        setProfile(nextProfile)
        setNextProfile(profiles[++index%3])
      }
    }
  }
```

The last thing to do is get the current profile card to reset position automatically after an uncompleted swipe. To do this, we will make an Animation with Animated.parallel to reset both the x and y position back to zero. Here is what I used:
```js
const reset = Animated.parallel([
    Animated.timing(translateX,{
      toValue:0,
      duration:200,
      useNativeDriver:true
    }),
    Animated.timing(translateY,{
      toValue:0,
      duration:200,
      useNativeDriver:true
    })
  ])
```
And now we just need to call reset inside our handlePanStateChange method when the user doesn't swipe far enough.
```js
const handlePanStateChange = ({nativeEvent}) =>{
    const {state, translationX} = nativeEvent
    if(state === 5){ //When the user takes their finger off the screen
      if(translationX > 185 || translationX < -185){
        setProfile(nextProfile)
        setNextProfile(profiles[++index%3])
      }
      else reset.start()
    }
  }
```
And that's it! Our cards are now swipeable and appear as though we are swiping off the top of a deck of cards. In the next tutorial, I will show you how we can animate the top card off the screen while still allowing the card behind it to be interactable.