import * as React from 'react' ; import { StyleSheet , ViewStyle } from 'react-native' ; import { createNavigator , CreateNavigatorConfig , NavigationDescriptor , NavigationParams , NavigationProp , NavigationRoute , NavigationRouteConfigMap , NavigationScreenProp , NavigationState , NavigationSwitchProp , NavigationSwitchRouterConfig , SceneView , SwitchRouter , SupportedThemes , NavigationScreenConfig , } from 'react-navigation' ; import { TransitioningView , Transitioning , Transition , } from 'react-native-reanimated' ; const DEFAULT_TRANSITION = ( < Transition . Together > < Transition . Out type = "fade" durationMs = { 200 } interpolation = "easeIn" / > < Transition . In type = "fade" durationMs = { 200 } / > < /Transition.Together>); type Props = { navigationConfig : NavigationAnimatedSwitchConfig ; navigation : NavigationProp < NavigationState > ; descriptors : { [ key ] : NavigationDescriptor < NavigationParams , NavigationAnimatedSwitchOptions , NavigationSwitchProp < NavigationRoute , any > > ; } ; screenProps ? : unknown ; } ; class AnimatedSwitchView extends React . Component < Props > { componentDidUpdate ( prevProps ) { const { state : prevState } = prevProps . navigation ; const prevActiveKey = prevState . routes [ prevState . index ] . key ; const { state } = this . props . navigation ; const activeKey = state . routes [ state . index ] . key ; if ( activeKey !== prevActiveKey && this . containerRef . current ) { this . containerRef . current . animateNextTransition ( ) ; } } private containerRef = React . createRef < TransitioningView > ( ) ; render ( ) { const { navigationConfig , screenProps } = this . props ; const { state } = this . props . navigation ; const activeKey = state . routes [ state . index ] . key ; const descriptor = this . props . descriptors [ activeKey ] ; const ChildComponent = descriptor . getComponent ( ) ; const transition = ( navigationConfig && navigationConfig . transition ) || DEFAULT_TRANSITION ; const transitionViewStyle = ( navigationConfig && navigationConfig . transitionViewStyle ) || null ; return ( < Transitioning . View ref = { this . containerRef } transition = { transition } style = { [ styles . container , transitionViewStyle ] } > < SceneView component = { ChildComponent } navigation = { descriptor . navigation } screenProps = { screenProps } / > < /Transitioning.View>); } } export type NavigationAnimatedSwitchConfig = NavigationSwitchRouterConfig & { transition ? : React . ReactNode ; transitionViewStyle ? : ViewStyle ; } ; export type NavigationAnimatedSwitchOptions = { } ; export type NavigationAnimatedSwitchProp < State = NavigationRoute , Params = NavigationParams > = NavigationScreenProp < State , Params > & { jumpTo : ( routeName : string , key ? : string ) => void ; } ; export type NavigationAnimatedSwitchScreenProps < Params = NavigationParams , ScreenProps = unknown > = { theme : SupportedThemes ; navigation : NavigationAnimatedSwitchProp < NavigationRoute , Params > ; screenProps : ScreenProps ; } ; export type NavigationAnimatedSwitchScreenComponent < Params = NavigationParams , ScreenProps = unknown > = React . ComponentType < NavigationAnimatedSwitchScreenProps < Params , ScreenProps > > & { navigationOptions ? : NavigationScreenConfig < NavigationAnimatedSwitchOptions , NavigationAnimatedSwitchProp < NavigationRoute , Params > , ScreenProps > ; } ; export default function createAnimatedSwitchNavigator ( routeConfigMap , switchConfig = { } ) { const router = SwitchRouter ( routeConfigMap , switchConfig ) ; const Navigator = createNavigator ( AnimatedSwitchView , router , switchConfig ) ; return Navigator ; } const styles = StyleSheet . create ( { container : { flex : 1 , } , } ) ;