In this article, we will be creating our own Animated Toast from scratch in React Native.
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
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
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',
],
};
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>
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>
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';
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>
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';
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
}
})
Add this new style to your Animated.View
component styles.
<Animated.View
style={[
{
padding: 20,
position: 'absolute',
width: '100%',
zIndex: 1
},
toastAnimatedStyle
]}
>
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)
}
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);
}
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;
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)