wix / react-native-navigation

A complete native navigation solution for React Native
https://wix.github.io/react-native-navigation/
MIT License
13.04k stars 2.67k forks source link

Shared Element transition breaks when using ScreenWrapper with SafeAreaContext #7497

Open Pietro-Putelli opened 2 years ago

Pietro-Putelli commented 2 years ago

🐛 Bug Report

In the app I need to use Redux and SafeAreaContext, therefore I created a ScreenWrapper component and wrap all screens into it, to provide the right contexts to all of them. Then when I try to create a sharedElement transition, using showModal, and not push because I need a transparent background, the showModal animation don't work, it works only when dismissing.

Expected behavior

The sharedElement transition should perform exactly as it does using push.

Actual Behavior

Using showModal, for the reason I've explained before, the sharedElement animation for opening (for dismissing it actually works) it doesn't work, I mean it's replaced by a cross fade transition.

Here's the code:

const ScreenWrapper = (Component, params) => {
  return function inject(props) {
    return (
      <Provider store={store}>
        <PersistGate loading={<></>} persistor={persistor}>
          <NavigationProvider value={{ componentId: props.componentId }}>
            <SafeAreaProvider>
              <Component {...params} {...props} />
            </SafeAreaProvider>
          </NavigationProvider>
        </PersistGate>
      </Provider>
    );
  };
};

Navigation.registerComponent("Screen1", () => ScreenWrapper(component));
Navigation.registerComponent("Screen2", () => ScreenWrapper(component));

Navigation.events().registerAppLaunchedListener(() => {
  Navigation.setRoot({
    root: {
      stack: {
        children: [
          {
            component: {
              name: 'Screen1',
            },
          },
        ],
      },
    },
  });
});

Navigation.showModal({
            component: {
              name: 'Detail',
              options: {
                modalPresentationStyle: 'fullScreen',
                animations: {
                  showModal: {
                    alpha: {
                      from: 0,
                      to: 1,
                      duration: 500,
                    },
                    sharedElementTransitions: [
                      {
                        fromId: `image.from`,
                        toId: `image.to`,
                        duration: 500,
                        interpolation: {type: 'spring', ...SPRING_CONFIG},
                      },
                    ],
                  },
                  dismissModal: {
                    alpha: {
                      from: 1,
                      to: 0,
                      duration: 500,
                    },
                    sharedElementTransitions: [
                      {
                        toId: `image.from`,
                        fromId: `image.to`,
                        duration: 500,
                        interpolation: {type: 'spring', ...SPRING_CONFIG},
                      },
                    ],
                  },
                },
              },
            },
          });

Maybe I've made mistakes with the wrapper logic. Thank you

fdecampredon commented 2 years ago

@Pietro-Putelli I had the same problem, I discovered that by passing initialWindowMetrics to SafeAreaProvider the problem disappear, I guess that if you don't the component will renderer nothing during the initial calculation