software-mansion / react-native-reanimated

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

Animations are not working after navigating to the same screen with react-navigation/drawer && react-navigation/bottom-tabs #6429

Open coderBeat opened 3 weeks ago

coderBeat commented 3 weeks ago

Description

I am using the react-native navigation for navigating between the screens. both drawer navigation and bottom navigation are being used:

    "@react-navigation/bottom-tabs": "^6.6.1",
    "@react-navigation/drawer": "^6.7.2",

I also the latest version from the react-native-reanimated: "react-native-reanimated": "^3.14.0",

I have the following screens:

screen A
screen B (contains reanimated animations with SVG)
screen C (contains congratulation screen that plays a lottie-react-native animation and fade animations using useSharedValue).

The structure is following:

- Drawer
             - Bottom Bar -> Contains Screen A
             - Screen B
             - Screen C

The problem is when I navigate the first time from Screen A -> Screen B -> Screen C, all animations works, but when navigating again with same steps, all the animations are freezed and no animation is displayed.

I am using the following command to navigate:

this.props.navigation.navigate("Thanks")

and this code to run the animation in Thanks Screen:

  useEffect(() => {
    const unsubscribe = navigation.addListener('focus', () => {
      setTimeout(() => {
        fadeInF();
      }, 100);
          });
    return unsubscribe;
  },[navigation]);

Why is this happening ?

Steps to reproduce

  1. Add @react-navigation/drawer and @react-navigation/bottom-tabs to the project.

  2. Build the screens according to the following structure:

    - Drawer
             - Bottom Bar -> Contains Screen A
             - Screen B
             - Screen C
  3. Navigate from Screen A -> Screen B -> Screen C -> Screen A

  4. Navigate again from Screen A -> Screen B -> Screen C -> Screen A (no animations works).

Snack or a link to a repository

https://github.com/react-native-community/reproducer-react-native

Reanimated version

3.15.0

React Native version

0.75.1

Platforms

Android, iOS

JavaScript runtime

Hermes

Workflow

React Native

Architecture

None

Build type

Debug app & dev bundle

Device

iOS simulator

Device model

iPhone 15 Pro

Acknowledgements

Yes

github-actions[bot] commented 3 weeks ago

Hey! 👋

The issue doesn't seem to contain a minimal reproduction.

Could you provide a snack or a link to a GitHub repository under your username that reproduces the problem?

MatiPl01 commented 3 weeks ago

Hey! How do you trigger these animations when you enter the screen? Do you reset animation progress and start animation again when you re-enter previously visited screen?

Your animations very likely don't play again because they are already finished, since the screen you re-visit is already rendered and wasn't unmounted when you navigated to another screen. Navigators keep screens mounted to optimize navigation between screens so your animations won't execute again unless you trigger them manually.

You may want to use the useFocusEffect hook or useIsFocused to check whether the screen is focused and reset the animation.

coderBeat commented 1 week ago

I was using the following for the navigation: this.props.navigation.navigate("ThankYou");

In addition, I used useEffect for resetting the animation, I verified that it is called every time, but animation only runs on the first attempt. Navigating to the same page again freezes the animation.

Currently, the only workaround which I found is to use Reset, which is very bad, since I lose all the history and all pages are forcefully rendered:

            this.props.navigation.reset({
              index: 0,
              routes: [
                {
                  name: "ThankYou",
                },
              ],
            });

What would be the difference b/w using useEffect and useFocusEffect ?

MatiPl01 commented 1 week ago

@coderBeat Could you please share a code snippet showing how you use useEffect? I will check if you are resetting the animation properly.

Generally, when dealing with screens in the navigator, you should use the useFocusEffect hook to check whether the particular screen is currently focused. Its callback is called when the screen becomes active, whilst useEffect is called only if its dependency list changes.

You can find here more details about useFocusEffect