Have you ever built an app, showed it to your friends or clients, and they complained that it didn’t “feel smooth”? Maybe they recommended adding fluid animations, but you’re not an animator.
Right now, your app looks jittery like this:
But you want it to look like this with animation:
Undoubtedly, animations enhance the app’s user experience. However, when it comes to actually implementing them, we have to perform these steps:
Although this is one approach to solve this problem, there is a minor issue: developing animations requires lots of skill and time. This is a major headache for small teams.
This is where React Native Reanimated comes in. It’s an open source React Native library (at around 6.5k stars on GitHub) that allows developers to implement animations.
Recently, the developer team has released version 3, which brings in major improvements. In this article, we will cover what’s new in React Native Reanimated.
Here’s what we’ll learn today:
According to the developers, most of the features are under-the-hood changes.
As of version 3, Reanimated now uses the Fabric architecture under the hood. This brings huge security and performance upgrades. As a result, this means that your app is secure and snappy.
For those who don’t know much about Fabric, let’s briefly cover the fundamentals and history.
Back in 2018, Facebook started developing a new renderer for the React Native library called Fabric. In the old process, React handled all UI operations via a sequence of cross-bridge steps. We can explain this via the following diagram:
As the diagram shows, there are four sections:
While this method works as intended, there was one major flaw: the JavaScript and Native components communicated by asynchronous JSON messages via the bridge. Sometimes, the bridge transmitted messages slowly, thus causing performance issues.
To solve this problem, Facebook built a new renderer called Fabric. It includes many benefits, some of which include:
Later on in the article, we will cover on how to migrate our codebase to use the Fabric architecture.
The team has removed support for the deprecated Reanimated 1 API. The reason for this was porting Fabric to the older API meant too much effort. Consequently, this meant that projects using the legacy version will not run on the latest version of Reanimated.
If your app relies on the legacy API, here are some steps you can take:
As of Reanimated 3, the library will not ship prebuilt binaries for Android. This means that the developer needs to have the Android NDK pre-installed before building their app. However, in most situations, this is not a problem since Android Studio already bundles the NDK.
Furthermore, it is important to note that the developer has to compile the C++ code of Animated from source. We will cover this in detail during our migration.
First, initialize a blank React Native project like so:
npx react-native init reactAnimatedNew #initialize the project cd reactAnimatedNew #navigate into project directory
Next, install the newest version of react-native-reanimated:
npm install react-native-reanimated@next #make sure that '@next is appended, otherwise NPM will install version 2!
When that’s done, let’s now tell React that we want to use the Fabric renderer instead of its legacy counterpart.
In this section, we will cover how to integrate Fabric in our project.
To build for Android, first navigate to android/gradle.properties
. Here, find the newArchEnabled
property and set it to true
:
#in android/gradle.properties: newArchEnabled=true
We‘ve instructed the compiler to enable Fabric for Android.
For iOS, run this command in your terminal:
cd ios #change the flag that enables/disables Fabric: RCT_NEW_ARCH_ENABLED=1 bundle exec pod install
Let’s see if everything works! To build your project, run this terminal command:
npx react-native run-android #in a new terminal window: npx react-native start
One important thing to note is that unlike previous versions, the library will compile Hermes from source. This means that the build times of our projects will increase.
Now that we have built our project using Fabric, let’s build a simple animation.
To do so, create a file called AnimatedRenderer.js
. Here, start by writing the following code:
import Animated, { useSharedValue, useAnimatedStyle, withSpring, } from "react-native-reanimated"; import { Button, View, Text } from "react-native"; export default function AnimationRenderer() { const height = useSharedValue(20); //this value is shared between worker threads const animatedStyles = useAnimatedStyle(() => { return { height: height.value, //change the height property of the component }; return ( <View> <Animated.View style={[{backgroundColor: 'blue'}, animatedStyles]}> <Text> This text space will expand</Text> </Animated.View> {/* When clicked, increment the shared value*/} {/* this will increase the height of the component.*/} <Button onPress={() => (height.value = height.value + 1)} title="Increase" //when clicked, increment 'height' /> </View> ); }); }
A few inferences from this code:
useSharedValue
Hook. This allows us to build animated valuesuseAnimatedStyles
Hook to tell React that we want to animate the height propertyanimatedStyles
variable to our Animated.View
component for animation purposesAs a final step, all that’s left for us is to render our custom component to the UI. To do so, modify your App.js
file like so:
//App.js import React from "react"; import { SafeAreaView } from "react-native"; import AnimationRenderer from "./AnimationRenderer"; export default function App() { return ( <SafeAreaView style={backgroundStyle}> <AnimationRenderer /> {/*render our custom component to the DOM */} </SafeAreaView> ); }
Notice that our animation is jittery. To smoothen it, we can use the withSpring
method:
//AnimationRenderer.js: <Button onPress={() => (offset.value = withSpring(offset.value + 10))} title="Increase" />;
This results in a more fluid animation:
The Reanimated library has the following alternatives:
Even though they are easier to use, Reanimated allows for more granular control and performance via worklets. Furthermore, with Fabric support, the library brings in more security and snappiness out of the box. When it comes to personal projects, Reanimated has always been a part of my arsenal.
Thank you so much for reading!
LogRocket is a React Native monitoring solution that helps you reproduce issues instantly, prioritize bugs, and understand performance in your React Native apps.
LogRocket also helps you increase conversion rates and product usage by showing you exactly how users are interacting with your app. LogRocket's product analytics features surface the reasons why users don't complete a particular flow or don't adopt a new feature.
Start proactively monitoring your React Native apps — try LogRocket for free.
Hey there, want to help make our blog better?
Join LogRocket’s Content Advisory Board. You’ll help inform the type of content we create and get access to exclusive meetups, social accreditation, and swag.
Sign up nowCompare Prisma and Drizzle ORMs to learn their differences, strengths, and weaknesses for data access and migrations.
It’s easy for devs to default to JavaScript to fix every problem. Let’s use the RoLP to find simpler alternatives with HTML and CSS.
Learn how to manage memory leaks in Rust, avoid unsafe behavior, and use tools like weak references to ensure efficient programs.
Bypass anti-bot measures in Node.js with curl-impersonate. Learn how it mimics browsers to overcome bot detection for web scraping.