8

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}
    />
  );
};
Dilhan Bhagat
  • 408
  • 1
  • 10
  • 20

4 Answers4

13

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 ;)

miknoup
  • 204
  • 2
  • 5
11

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.

  • How would I apply this to my flat list because I am still lost Please can you help me – Dilhan Bhagat Sep 14 '20 at 09:26
  • I would create a component called `FadeInView` or something similar. Then put this code inside of it. Then you can use `FadeInView` as a parent component e.g.``. – Benjamin Godlove Sep 14 '20 at 14:27
  • Please can you show me how I would do this with fade in and fade out – Dilhan Bhagat Sep 14 '20 at 15:08
  • 1
    @DilhanBhagat I believe that trying to fade out in the return of a useEffect won't actually work. Your component will be unmounted and disappear before the animation happens. You need to leave that component mounted and trigger the fade out animation through a visibility prop / condition. – Jason Masters Aug 10 '22 at 00:55
5

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>
  )
}

Jason Masters
  • 160
  • 2
  • 8
  • Should be the accepted answer. Trying to animate while juggling unmounting is a nightmare. Best to just use a perceived animation like you did. – jakeforaker Sep 29 '22 at 21:52
1

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>
Aliunco
  • 399
  • 2
  • 9