React-Native Add Fade in Animation

Viewed 10709

I am trying to make this card fade in every time the component loads and fade out after it unmount's using hooks but I am failing to do so and desperately need someones help. Please can you show me how to animate this card every-time it's loaded and unmounted using hooks

This is my component:

import React, { useState } from "react";

const Home = (props) => {
  const renderCard = ({ item }) => {
    return (
      //I am trying to add a fadein to this everytime it loads and fadout when It unmounts
      <View>
        <Text style={styles.day}>{item}</Text>
        <MealCards
          item={state[item]}
          navigation={navigation}
          onChange={onChange}
        />
        <View style={styles.divider} />
      </View>
    );
  };
  return (
    <FlatList
      data={days}
      keyExtractor={(item) => item}
      showsHorizontalScrollIndicator={false}
      renderItem={renderCard}
    />
  );
};
4 Answers

Wrap your component in an Animated.View and give it the fade in animation using opacity: https://reactnative.dev/docs/animated.

Something like

  const [fadeAnim] = useState(new Animated.Value(0));

  React.useEffect(() => {
    Animated.timing(fadeAnim, {
      toValue: 1,
      duration: 1000,
    }).start();
  }, []);

  return (
    <Animated.View
      style={{
        opacity: fadeAnim,
      }}
    >
      {props.children}
    </Animated.View>
  );

Above code would be for fading in. Fading out would be done in the return function of the useEffect.

I think that the best way to do this is using Reanimated.

import Animated, { FadeIn, FadeOut } from    'react-native-reanimated';

<Animated.View
            key={'uniqueKey'}
            entering={FadeIn.duration(400)}
            exiting={FadeOut.duration(400)}
        />

Extra tip: If you want to retrigger the animation you could just change the component key prop ;)

You can also use a library named react-native-fadeview-wrapper and you can easily cover all fade animations and it's also customizable.

<FadeView visible={isVisible}>
    {/** any components of yours */}
</FadeView>

Building off of @Benjamin Godlove's answer, here's a fully working fade in/out example.

I found that trying to fade out because of a useEffect return statement wouldn't work (I believe the component unmounts and unrenders before the animation has time to run), so instead I keep the component mounted and just effect opacity/visibility with a toggle.

type Props = {
  children: React.ReactNode;
  visible: boolean;
};

function FadePanel({children, visible}:Props){
  const fadeAnim = useRef(new Animated.Value(0)).current;
  React.useEffect(() => {
    if (visible) {
      Animated.timing(fadeAnim, {
        toValue: 1,
        duration: 1000,
        useNativeDriver: true,
      }).start();
    } else if (!visible) {
      Animated.timing(fadeAnim, {
        toValue: 0,
        duration: 1000,
        useNativeDriver: true,
      }).start();
    }
  }, [visible]);
  return (
    <Animated.View
      style={{
        opacity:fadeAnim
      }}
    >
      {children}
    </Animated.View>
  )
}

Related