react-native-reanimated: Animated.View does not update exiting/entering layout animations dynamically

Description

Changing exiting or entering properties on an animated component doesn’t have an effect.

Since createAnimatedView only ever registers entering or exiting animations during _setComponentRef, updates to exiting and entering don’t ever take effect (i.e. componentDidUpdate in animated components doesn’t ever re-register exiting and entering via LayoutAnimationRepository.registerConfig).

I tried the obvious “fix,” which was to call registerConfig with an updated exiting/entering during componentDidUpdate, but that led to a crash. I’m likely misunderstanding the threading/data-usage of configurations once registered. The real fix would be to update registered configurations with new layout animations whenever those properties change.

Steps to reproduce

  1. Create an Animated.View with exiting={LightSpeedOutLeft}, and key={42}
  2. Dynamically update its exiting to LightSpeedOutRight. Make sure component renders before next step.
  3. Change key to "Thank you very much, Mr. Roboto". Once again, this step should only be taken AFTER step 2 has rendered, or else you’ll simply be setting a different animation on a new view.

RESULT: View animates out left. EXPECTED: View animates out right.

Snack or a link to a repository

https://snack.expo.dev/@fivecar/reanimated2-layout-animations-not-updating

Reanimated version

2.10.0

React Native version

0.69.3

Platforms

iOS

JavaScript runtime

JSC

Workflow

React Native (without Expo)

Architecture

Paper (Old Architecture)

Build type

Debug mode

Device

iOS simulator

Device model

No response

Acknowledgements

Yes

About this issue

  • Original URL
  • State: closed
  • Created 2 years ago
  • Reactions: 5
  • Comments: 17 (3 by maintainers)

Most upvoted comments

I encountered the same problem and found a workaround using a custom animation as described here: https://docs.swmansion.com/react-native-reanimated/docs/api/LayoutAnimations/customAnimations#custom-exiting-animation

In my case I want to set the exit animation to either SlideOutLeft or SlideOutRight depending on which way the view was swiped. My solution looks something like this:

import Animated, {
    SlideOutLeft,
    SlideOutRight,
    useSharedValue,
} from 'react-native-reanimated';

const slideOutLeftAnimation = new SlideOutLeft().build();
const slideOutRightAnimation = new SlideOutRight().build();

const MyComponent = () => {
    const exitDirection = useSharedValue('left');

    const CustomExitingAnimation = (values) => {
        'worklet';

        return exitDirection.value === 'left'
            ? slideOutLeftAnimation(values)
            : slideOutRightAnimation(values);
    };

    return (
        <Animated.View
            exiting={CustomExitingAnimation}
            onTouchMove={() => {
                exitDirection.value = someCondition ? 'left' : 'right';
            }}
        />
    );
}

The example by @bviebahn is the correct way to do this, using shared values and the animation builder. The example even extends a reanimated preset which is great for people looking for a copy paste solution. Great contribution!

I encountered the same problem and found a workaround using a custom animation as described here: https://docs.swmansion.com/react-native-reanimated/docs/api/LayoutAnimations/customAnimations#custom-exiting-animation

In my case I want to set the exit animation to either SlideOutLeft or SlideOutRight depending on which way the view was swiped. My solution looks something like this:

import Animated, {
    SlideOutLeft,
    SlideOutRight,
    useSharedValue,
} from 'react-native-reanimated';

const slideOutLeftAnimation = new SlideOutLeft().build();
const slideOutRightAnimation = new SlideOutRight().build();

const MyComponent = () => {
    const exitDirection = useSharedValue('left');

    const CustomExitingAnimation = (values) => {
        'worklet';

        return exitDirection.value === 'left'
            ? slideOutLeftAnimation(values)
            : slideOutRightAnimation(values);
    };

    return (
        <Animated.View
            exiting={CustomExitingAnimation}
            onTouchMove={() => {
                exitDirection.value = someCondition ? 'left' : 'right';
            }}
        />
    );
}

This works great give this a try if you’re trying to do some dynamic animations based on a react state and change out that state for useSharedValue. Thank you !!!