fix: `skipExiting` not working on Android
Summary
Issue description
For some reason, componentWillUnmount was called too late on android and the ShadowNode removal mutation triggered the exiting layout animation before the componentWillUnmount was called. Since we used componentWillUnmount to disable exiting animations for LayoutAnimationConfigs on which the skipExiting prop was used, the disabled flag was set in CPP layout animations config object after the exiting animation started.
How it was fixed?
The fix is not perfect, but I think that it is sufficient, at least for most cases, because people don't usually modify skipExiting prop at all.
Instead of waiting until the component unmounts, I mark exiting animations as disabled just after the component mounts (only if skipExiting is set to true) and then update it every time that the skipExiting value changes. In most cases it doesn't change at all, so in effect I set the skipExiting value in CPP only once.
Example recordings
| Before | After |
|---|---|
Test plan
Copy this code and paste to the EmptyExample to see how it works.
Code snippet
import { useEffect, useState } from 'react';
import { StyleSheet } from 'react-native';
import Animated, {
FadeOut,
LayoutAnimationConfig,
} from 'react-native-reanimated';
export default function App() {
const [show, setShow] = useState(true);
useEffect(() => {
setTimeout(() => {
setShow(false);
}, 1000);
}, []);
return (
show && (
<LayoutAnimationConfig skipEntering skipExiting>
<Animated.View exiting={FadeOut} style={styles.box} />
</LayoutAnimationConfig>
)
);
}
const styles = StyleSheet.create({
box: {
width: 200,
height: 200,
backgroundColor: 'red',
},
});
After consulting with @bartlomiejbloniarz, it turned out that this approach also breaks this case when the exiting animation should be triggered:
<LayoutAnimationConfig skipEntering skipExiting>
{show && <Animated.View exiting={FadeOut} style={styles.box} />}
</LayoutAnimationConfig>
I will have to work on a different solution then.
Closed as RN 0.82 fixes the issue