software-mansion / react-native-reanimated

React Native's Animated library reimplemented
https://docs.swmansion.com/react-native-reanimated/
MIT License
8.61k stars 1.27k forks source link

Entering and/or layout animation flickering when SafeAreaView is a first parent of an animated component #6046

Closed exploIF closed 3 weeks ago

exploIF commented 1 month ago

Description

When an animated component is placed directly inside SafeAreaView from react-native or from react-native-safe-area-context it jumps down after finishing entering animation, also layout animations are triggered while component is mounting.

https://github.com/software-mansion/react-native-reanimated/assets/74370735/114cf413-e5fe-41a9-916f-66aa768bd91b

Steps to reproduce

Paste the following code into EmptyExample.tsx

import {SafeAreaView, StyleSheet, View} from 'react-native';
import React from 'react';
import Animated, {FadeIn} from 'react-native-reanimated';

const animation = FadeIn.delay(1000).duration(2000);

export default function EmptyExample() {
  return (
    <SafeAreaView>
      <View style={styles.greyBox} />
      <Animated.View entering={animation}>
        <View style={styles.redAnimatedBox} />
      </Animated.View>
    </SafeAreaView>
  );
}
const styles = StyleSheet.create({
  greyBox: {
    backgroundColor: 'grey',
    height: 100,
    width: '100%',
  },
  redAnimatedBox: {
    backgroundColor: 'red',
    height: 100,
    width: '100%',
  },
});

Snack or a link to a repository

no

Reanimated version

3.11.0

React Native version

0.74.1

Platforms

iOS

JavaScript runtime

Hermes

Workflow

React Native

Architecture

Fabric (New Architecture)

Build type

Debug app & dev bundle

Device

iOS simulator

Device model

iPhone SE (3rd generation)

Acknowledgements

Yes

exploIF commented 1 month ago

Solution

Wrap content with additional container

import {SafeAreaView, StyleSheet, View} from 'react-native';
import React from 'react';
import Animated, {FadeIn} from 'react-native-reanimated';

const animation = FadeIn.delay(1000).duration(2000);

export default function EmptyExample() {
  return (
    <SafeAreaView>
+      <View style={styles.container}>
        <View style={styles.greyBox} />
        <Animated.View entering={animation}>
          <View style={styles.redAnimatedBox} />
        </Animated.View>
+      </View>
    </SafeAreaView>
  );
}
const styles = StyleSheet.create({
+ container: {
+   flex: 1,
+ },
  greyBox: {
    backgroundColor: 'grey',
    height: 100,
    width: '100%',
  },
  redAnimatedBox: {
    backgroundColor: 'red',
    height: 100,
    width: '100%',
  },
});