react-native-reanimated
react-native-reanimated copied to clipboard
React-native-reanimated v3 flickers inside SafeAreaView
Description
I have just updated my React Native app to the latest version of Expo SDK. The app uses native code and dev clients. As part of the update process, I deleted the iOS and android folders to ensure a clean installation. During the Expo update, react-native-reanimated was updated from version 2.14.4 to version 3.3.0.
However, after the update, I'm experiencing various issues with animations. Specifically, the animations lag significantly only the first time they are executed. Subsequent executions seem to work fine.
I have uploaded videos to show the problem.
https://res.cloudinary.com/dynsmaeo3/video/upload/ac_none,e_volume:-100/v1689971871/SPOTLIVE-STATIC/2_-SD_480p_mjausq.mov https://res.cloudinary.com/dynsmaeo3/video/upload/ac_none/v1689971822/SPOTLIVE-STATIC/stackoveflow-_SD_480p_fr1zlg.mov
After several tests I managed to find that if I don't use the react-native SafeAreaView component the problem goes away. I created a blank app with a fresh install of expo to make the problem replicable.
How can I fix this bug?
Steps to reproduce
- install expo sdk 49 on bare workflow
- use entering animations of components inside a SafeAreaView
Snack or a link to a repository
https://github.com/NiccoloCase/reanimated-bug-test
Reanimated version
3.3.0
React Native version
0.72.3
Platforms
Android, iOS
JavaScript runtime
None
Workflow
Expo bare workflow
Architecture
Paper (Old Architecture)
Build type
Debug mode
Device
Real device
Device model
iPhone 12
Acknowledgements
Yes
I encountered the same problem after upgrading from Expo 48 to 49, and from Reanimated 2.14 to 3.3. A temporary solution to my problem is using useSafeAreaInsets
from react-native-safe-area-context
and placing it as padding in the RootContainer. The solution of course depends on your project structure and SafeAreaView usage.
@wojciechkrol Could you show the part of code you modified? I still have this problem
I think this is a really serious problem but also easily replicable, is it possible that no one has done anything in recent months?
@NiccoloCase Instead of:
function RootComponent({children}) {
return <SafeAreaView>{children}</SafeAreaView>;
}
use
function RootComponent({children}) {
const insets = useSafeAreaInsets();
return <View style={{paddingTop: insets.top, ...}}>{children}</View>;
}
@NiccoloCase Instead of:
function RootComponent({children}) { return <SafeAreaView>{children}</SafeAreaView>; }
use
function RootComponent({children}) { const insets = useSafeAreaInsets(); return <View style={{paddingTop: insets.top, ...}}>{children}</View>; }
It worked for me as well. Thanks!
The problem is that in this way I would have to change every single screen of the app, since I don't use SafeAreaView only in the root file. Isn't there anyone who has a better idea?
What worked for me is wrapping the Animated.View inside another <View>
component.
<SafeAreaView style={{ flex: 1 }}>
<View>
<Animated.View
entering={FadeIn.duration(500)}
</Animated.View>
</View>
</SafeAreaView>
I didn't experience flickering after doing this.
Our app is very large and has a lot of screens and I noticed that the problem also occurs where there is no safe area view. so the solution in these cases does not solve the problem for me, but it is easily replicable!