pfinferno
pfinferno

Reputation: 1955

How to fade one component in while another fades out?

In a class component, I have two views, one as a placeholder and one for image. The placeholder shows until some state changes (when the image finishes loading), and then the image shows. I am trying to add some animation and have the image fade-in and the placeholder fade-out when the state changes instead.

Below is the relevant render function for the two views:

renderImage = (filePath: string): JSX.Element => {
    const { isImageLoaded } = this.state;
    if (isImageLoaded) {
        return (
            <View style={Styles.imageContainer}>
                    <Image source={{ uri: filePath, cache: 'reload' }}/>
            </View>
        );
    }

    return (
        <View style={Styles.placeholderContainer}>
        </View>
    );
};

I understand I need to change the views to Animated.View and have fade-in/fade-out functions like so:

Animated.timing(this.state.opacity, {
      toValue: 1,
      duration: 500,
      useNativeDriver: true,
    }).start();

Is the correct way to call the fade-in/fade-out functions in the callback of the setState for the isImageLoaded state? Or is there a way to trigger the animations without manually calling them in setState ?

Upvotes: 3

Views: 4773

Answers (1)

Kipnoedels
Kipnoedels

Reputation: 1404

If you can, I would recommend using react-native-reanimated (v2). It has a feature exactly for this usecase using entering and exiting prop. Example using reanimated:

if (shouldShow) {
   return(
      <Animated.View entering={FadeIn} exiting={FadeOut}>
         <Content/>
      </Animated.View>
   )
}

See: https://www.youtube.com/watch?v=6UXfS6FI674

If it's not possible, you have to build your own implementation. Could be something like this:

handleHideAnimation = () => {
   Animated.timing(value, {
      toValue: 0,
      duration: 500,
    }).start(() => handleUnmountComponent);
}

Upvotes: 5

Related Questions