React native not rerendering after state change until user input

Viewed 21

My component isnt rerendering until after the user presses a button. I have the user hit a button which animates a change to the position/width of a component, then in the callback I am doing a state change. I was hoping that the re-render would occur after the animation, but it is happening before the next user input. I was wondering how to get the component to rerender immediately once the animation completes?

video: https://imgur.com/a/EJHC1H0

import React, {useEffect, useRef, useState} from 'react';
import { View, Text, StyleSheet, Button, Animated } from 'react-native';
import GalleryRow from './GalleryRow'

const ImageScreen = () => {

  const [currentRow, setCurrentRow] = useState(0)

  const thirdRowTopValue = new Animated.Value(0)
  const secondRowTopValue = new Animated.Value(10)
  const firstRowTopValue = new Animated.Value(20)
  const frontRowTopValue = new Animated.Value(90)

  const thirdRowWidthValue = new Animated.Value(50)
  const secondRowWidthValue = new Animated.Value(70)
  const firstRowWidthValue = new Animated.Value(100)
  const frontRowWidthValue = new Animated.Value(80)

  const inputRange = [0, 100];
  const outputRange = ["0%", "100%"]

  const thirdRowanimatedTop = thirdRowTopValue.interpolate({inputRange, outputRange});
  const secondRowanimatedTop = secondRowTopValue.interpolate({inputRange, outputRange});
  const firstRowanimatedTop = firstRowTopValue.interpolate({inputRange, outputRange});
  const frontRowanimatedTop = frontRowTopValue.interpolate({inputRange, outputRange});

  const thirdRowanimatedWidth = thirdRowWidthValue.interpolate({inputRange, outputRange});
  const secondRowanimatedWidth = secondRowWidthValue.interpolate({inputRange, outputRange});
  const firstRowanimatedWidth = firstRowWidthValue.interpolate({inputRange, outputRange});
  const frontRowanimatedWidth = frontRowWidthValue.interpolate({inputRange, outputRange});

  function moveForward() {
    Animated.parallel([
      Animated.timing(thirdRowTopValue, {
        toValue: 10,
        useNativeDriver: false
      }),
      Animated.timing(secondRowTopValue, {
        toValue: 20,
        useNativeDriver: false
      }),
      Animated.timing(firstRowTopValue, {
        toValue: 90,
        useNativeDriver: false
      }),
      Animated.timing(frontRowTopValue, {
        toValue: 100,
        useNativeDriver: false
      }),
      //
      Animated.timing(thirdRowWidthValue, {
        toValue: 70,
        useNativeDriver: false
      }),
      Animated.timing(secondRowWidthValue, {
        toValue: 100,
        useNativeDriver: false
      }),
      Animated.timing(firstRowWidthValue, {
        toValue: 80,
        useNativeDriver: false
      }),
      Animated.timing(frontRowWidthValue, {
        toValue: 30,
        useNativeDriver: false
      }),
    ]).start(() => {
      setCurrentRow(currentRow + 1)
    })

  }

  function moveBackward() {
    Animated.parallel([
      Animated.timing(thirdRowTopValue, {
        toValue: -20,
        useNativeDriver: false
      }),
      Animated.timing(secondRowTopValue, {
        toValue: 0,
        useNativeDriver: false
      }),
      Animated.timing(firstRowTopValue, {
        toValue: 10,
        useNativeDriver: false
      }),
      Animated.timing(frontRowTopValue, {
        toValue: 20,
        useNativeDriver: false
      }),
      //
      Animated.timing(thirdRowWidthValue, {
        toValue: 30,
        useNativeDriver: false
      }),
      Animated.timing(secondRowWidthValue, {
        toValue: 50,
        useNativeDriver: false
      }),
      Animated.timing(firstRowWidthValue, {
        toValue: 70,
        useNativeDriver: false
      }),
      Animated.timing(frontRowWidthValue, {
        toValue: 100,
        useNativeDriver: false
      }),
    ]).start(() => {
      setCurrentRow(currentRow - 1)
    })
  }



  return <View style={styles.page}>
  <View style={styles.parentStyle}>
  <Animated.View style={[styles.thirdRow, {top: thirdRowanimatedTop, width: thirdRowanimatedWidth}]}>
    <GalleryRow images={[
      require('../images/image1.png'),
      require('../images/image2.png'),
      require('../images/image3.png'),
    ]}/>
  </Animated.View>
  <Animated.View style={[styles.secondRow, {top: secondRowanimatedTop, width: secondRowanimatedWidth}]}>
  <GalleryRow images={[
    require('../images/image4.png'),
    require('../images/image5.png'),
    require('../images/image6.png'),
  ]}/>
  </Animated.View>
  <Animated.View style={[styles.firstRow, {top: firstRowanimatedTop, width: firstRowanimatedWidth}]}>
  <GalleryRow images={[
    require('../images/image7.png'),
    require('../images/image8.png'),
    require('../images/image9.png'),
  ]}/>
  </Animated.View>
  <Animated.View style={[styles.frontRow, {top: frontRowanimatedTop, width: frontRowanimatedWidth}]}>
  <GalleryRow images={[
    require('../images/image10.png'),
    require('../images/image11.png'),
    require('../images/image12.png'),
  ]}/>
  </Animated.View>
  </View>
  <View style={styles.button}>
    <Button title="Forward" onPress={moveForward}/>
  </View>
  <View style={styles.button}>
    <Button title="Backward" onPress={moveBackward}/>
  </View>

  </View>;
}

const styles = StyleSheet.create({
  page: {
    height: 800
  },
  parentStyle: {
    borderWidth: 5,
    borderColor: 'black',
    height: 300,
    overflow: 'hidden'
  },
  frontRow: {
    position: 'absolute',
    top:'90%',
    alignSelf: 'center',
    width: '80%',
  },
  firstRow: {
    position: 'absolute',
    top:'20%',
    alignSelf: 'center',
    width: '100%',
  },
  secondRow: {
    position: 'absolute',
    top:'10%',
    alignSelf: 'center',
    width: '70%',
  },
  thirdRow: {
    position: 'absolute',
    top:0,
    alignSelf: 'center',
    width: '50%',
  },
  button: {
    padding: 50
  }
});

export default ImageScreen;


  [1]: https://imgur.com/a/EJHC1H0
0 Answers
Related