DEV Community

Cover image for How to create an Animated Toast with React Native Re-Animated.
Babalola Macaulay
Babalola Macaulay

Posted on

How to create an Animated Toast with React Native Re-Animated.

In this article, we will be creating our own Animated Toast from scratch in React Native.

How to create an Animated Toast with React Native Re-Animated

React Native is a popular open-source Javascript framework, created and managed by Meta (They used to be known as Facebook).

NOTE: This article assumes prior knowledge of basics of react native, and i will not be explaining how to install or setup react native on your computer.

You should know that there's not just one way to achieve animations in React Native. React Native has it's own Animated library, for really nice fluid animations that are very easy to create.

However, we will be using React Native Reanimated created and managed by the awesome team at swmansion.

Animations done using React Native Reanimated are even more smooth and cooler, as animation and event handling logic off of the JavaScript thread and onto the UI thread.

Now let's get into real code...

We'll start by creating our new React Native project by running the code in our terminal:

npx react-native init AnimatedToastExample
Enter fullscreen mode Exit fullscreen mode

Feel free to run your new project on a simulator or a real device using npx react-native run android

Next, we install our package for animation

npm i react-native-reanimated
Enter fullscreen mode Exit fullscreen mode

To complete our react-native-reanimated setup, go to the root of your project and add this to your babel.config.js file:

 module.exports = {
    presets: [
      ...
    ],
    plugins: [
      ...
      'react-native-reanimated/plugin',
    ],
  };
Enter fullscreen mode Exit fullscreen mode

Don't forget to run npx pod-install if you are developing for iOS.

Now we're ready to start animating our React Native Components.

Create our button component

<TouchableOpacity
    style={{
        backgroundColor: 'teal',
        alignSelf: 'center',
        padding: 10,
        marginTop: 40,
        borderRadius: 4
    }}
    onPress={showToast}
>
    <Text style={{ color: 'white' }}>
        Show Toast
    </Text>
</TouchableOpacity>
Enter fullscreen mode Exit fullscreen mode

Create our toast component

<View
    style={[{
        padding: 20,
        position: 'absolute',
        top: 40,
        width: '100%',
        zIndex: 1
    }]}
>
    <View
        style={{
            backgroundColor: 'teal',
            padding: 10,
            borderRadius: 4,
        }}
    >
        <Text style={{ color: 'white' }}>
            This is a toast message
        </Text>
    </View>
</View>
Enter fullscreen mode Exit fullscreen mode

Now, before we animate our toast, let's import Animated from our animation library and change our the wrapping View component to use Animated.View instead.

import Animated from 'react-native-reanimated';
Enter fullscreen mode Exit fullscreen mode

Change the View on our component to Animated.View to look like this:

<Animated.View
    style={[{
        padding: 20,
        position: 'absolute',
        top: 40,
        width: '100%',
        zIndex: 1
    }]}
>
    <View
        style={{
            backgroundColor: 'teal',
            padding: 10,
            borderRadius: 4,
        }}
    >
        <Text style={{ color: 'white' }}>
            This is a toast message
        </Text>
    </View>
</Animated.View>
Enter fullscreen mode Exit fullscreen mode

Next, inside the style block of our animated component, we need to add styles that can be animated. What we want to do is change the top value to a value that makes is completely hidden from view, at the top of our screen.

Let's import 2 hooks from our animation library: useAnimatedStyle and useSharedValue:

import { useAnimatedStyle, useSharedValue } from 'react-native-reanimated';
Enter fullscreen mode Exit fullscreen mode
useSharedValue

This hook allows you to create a value that can be changed at any point in your code, and the change can be listed to by other animation hooks.
It takes the initial value you as the only argument.

useAnimatedStyle

This hook takes a callback as it's argument and returns a style object.
This hook will listen for changes in any of the values returned in it's style object, and effect these changes in your view component.

We will use these 2 hooks to create an initial top value for our Toast that hides is completely from viwew, and then listen for changes in that value, so that when we click our button and the value is changed, the toast will animate to the new top value.

hide toast container

const toastTopPosition = useSharedValue(-Dimensions.get('window').height)

const toastAnimatedStyle = useAnimatedStyle(() => {
    return {
        top: toastTopPosition.value
    }
})
Enter fullscreen mode Exit fullscreen mode

Add this new style to your Animated.View component styles.

<Animated.View
    style={[
        {
            padding: 20,
            position: 'absolute',
            width: '100%',
            zIndex: 1
        },
        toastAnimatedStyle
    ]}
>
Enter fullscreen mode Exit fullscreen mode

Once you reload your App, you should see your toast container is now completely hidden.

Show toast on button click()

Now we will handle our button click and show our toast immediately. At this point, all we need to complete our animations is to change the value we created with useSharedValue

const showToast = () => {
    toastTopPosition.value = withTiming(40)
}
Enter fullscreen mode Exit fullscreen mode

You will notice that we just used another hook from react-native-reanimated.

withTiming

This hook helps us to animate a change in our values.

Reload your app to see complete changes.

To wrap this up, we'll add a setTimeout function to our showToast function to make our toast disappear after a few seconds.

const showToast = () => {
    toastTopPosition.value = withTiming(40)

    setTimeout(() => {
        toastTopPosition.value = withTiming(-Dimensions.get('window').height)
    }, 2000);
}
Enter fullscreen mode Exit fullscreen mode

Now your final code should look something like this:

import React from 'react';
import {
    SafeAreaView,
    Text,
    TouchableOpacity,
    Dimensions,
    View,
} from 'react-native';
import Animated, { useAnimatedStyle, useSharedValue, withTiming } from 'react-native-reanimated';

import {
    Header,
} from 'react-native/Libraries/NewAppScreen';

const App = () => {
    const toastTopPosition = useSharedValue(-Dimensions.get('window').height)

    const toastAnimatedStyle = useAnimatedStyle(() => {
        return {
            top: toastTopPosition.value
        }
    })

    const showToast = () => {
        toastTopPosition.value = withTiming(40)

        setTimeout(() => {
            toastTopPosition.value = withTiming(-Dimensions.get('window').height)
        }, 2000);
    }

    return (
        <SafeAreaView style={{ flex: 1 }}>
            <Header />

            <Animated.View
                style={[
                    {
                        padding: 20,
                        position: 'absolute',
                        width: '100%',
                        zIndex: 1
                    },
                    toastAnimatedStyle
                ]}
            >
                <View
                    style={{
                        backgroundColor: 'teal',
                        padding: 10,
                        borderRadius: 4,
                    }}
                >
                    <Text style={{ color: 'white' }}>
                        This is a toast message
                    </Text>
                </View>
            </Animated.View>

            <View
                style={{
                    flex: 1,
                    backgroundColor: 'white'
                }}
            >
                <TouchableOpacity
                    style={{
                        backgroundColor: 'teal',
                        alignSelf: 'center',
                        padding: 10,
                        marginTop: 40,
                        borderRadius: 4
                    }}
                    onPress={showToast}
                >
                    <Text style={{ color: 'white' }}>
                        Show Toast
                    </Text>
                </TouchableOpacity>
            </View>
        </SafeAreaView>
    );
};

export default App;

Enter fullscreen mode Exit fullscreen mode

React Native ReAnimated Toast


Feel free to let me know what you think, and if this article has helped you in any way, please don't hesitate to give it a ♡ and share 👍🏽.

Top comments (0)