Skip to content

Instantly share code, notes, and snippets.

@satya164
Last active August 15, 2022 02:28
Show Gist options
  • Save satya164/34577ee6ef44e1a3a0147f3ebf88e184 to your computer and use it in GitHub Desktop.
Save satya164/34577ee6ef44e1a3a0147f3ebf88e184 to your computer and use it in GitHub Desktop.
React Navigation Shared Navigator

Shared Navigator

This is a UI and router agnostic navigator that aims to make it easier to build navigators with shared transitions between screens. All it does is keep track of animations in various screens so that the UI code can focus on animations instead.

Basic API

The basic API looks like this:

const Shared = createSharedNavigator(StackRouter);

// …

<Shared.Navigator>
  <Shared.Screen name="Home" />
  <Shared.Screen name="Profile" />
</Shared.Navigator>;

But the core of the functionality is contained within the built-in hooks. A screen in a basic navigator with simple enter & exit animations may look like this:

const translateX = useScreenTransition(0, {
  enter: (config) => ({
    animation: 'spring',
    velocity: config.velocity,
    toValue: 10,
  }),
  exit: (config) => ({
    animation: 'spring',
    velocity: config.velocity,
    toValue: 0,
  }),
});

The screen will stay mounted if any animations are running.

Another hook that’s exposed is useDataForNextScreen which let’s us pass arbitrary data to the next screen. This is similar to passing params, but unlike params, they are not intended for business logic. One of the ways it can be used is to pass layout information from the previous screen.

useDataForNextScreen('some-id', async () => {
  const layout = await viewRef.measureLayout();
  return layout;
});

Navigation animations won’t start until the async callbacks to useDataForNextScreen are resolved. This allows for measuring screen elements before transitioning to the new screen to be able to perform shared element transitions.

Similarly, the hook useDataFromPreviousScreen can be used to read this data.

const layout = useDataFromPreviousScreen(
  'some-id',
  { height: 0, width: 0 } /* default value */
);

This data can then be used alongside useScreenTransition to facilitate shared element transitions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment