React Native: Animation on unmount

1.8k Views Asked by At

I have a component a component like which takes a prop and it renders based on this prop. Every time this prop changes and the component re-renders, I want the the new component to come up from like 20dp and the old component to goes down like 20dp and disappear. I achieved the first one (the ease in) but I dont know what to achieve the second one (the ease out). I tought that I have to do it on the return method of useEffect(unmount) but the Animated doesnt seem to work onMount.

function Component({status}: Props) {
if (status === 'x') return <AnimatedView status={status}><View> xxx <View /><AnimatedView />

<AnimatedView status={status}><View> yyy <View /><AnimatedView />
}
function AnimatedView ({status}: AnimatedProps) {
  const animated = useRef(new Animated.Value(status === 'x' ? 1 : 0))
    .current;

  useEffect(() => {
    const animation = Animated.timing(animated, {
      toValue: status === 'x' ? 1 : 0,
      duration: 200,
      useNativeDriver: true
    });
    animation.start();
    return () => {
      animation.stop();
    };
  }, [animated, status]);
}
 const styles = {
    transform: [
      {
        translateY: animated.interpolate({
          inputRange: [0, 1],
          outputRange: status === 'x' ? [20, 0] : [0, 20]
        })
      }
    ],
    opacity: animatedFormHeader.interpolate({
      inputRange: [0, 1],
      outputRange:  status === 'x' ? [0, 1] : [1, 0]
    })
  };

Is there any way to achieve this with 'react-native' Animated? Should I use another API? Can I have some examples? Actually I think I should re-write the whole thing because I don't think its a good idea that the animation happens based on the prop. I just want to animate this component onmount and on unmount.

1

There are 1 best solutions below

1
On

I have created a component based on what i understood from above, hope this is the way you wanted...

snack: https://snack.expo.io/yjEX_u_Tu


export default ({ status }) => {
  const [text, setText] = useState('');
  const value = useRef(new Animated.Value(0)).current;

  useEffect(() => {
    const animation = Animated.timing(value, {
      toValue: 1,
      duration: 500,
    });
    animation.start(({ finished }) => {
      if (finished) {
        console.log(finished);
        setText(status ? 'Hi' : 'Bye');
        Animated.timing(value, {
          toValue: 0,
          duration: 500,
        }).start();
      }
    });
  }, [status]);

  const translateY = value.interpolate({
    inputRange: [0, 1],
    outputRange: [0, 20],
  });

  const opacity = value.interpolate({
    inputRange: [0, 1],
    outputRange: [1, 0.2],
  });
  return (
    <Animated.View
      style={[styles.container, { opacity, transform: [{ translateY }] }]}>
      <Animated.Text style={{ color: 'white' }}>{text}</Animated.Text>
    </Animated.View>
  );
};