Skip to content

Instantly share code, notes, and snippets.

@phuochau
Last active October 2, 2019 16:50
Show Gist options
  • Save phuochau/8281740beb39b823df4e2300e3582ff1 to your computer and use it in GitHub Desktop.
Save phuochau/8281740beb39b823df4e2300e3582ff1 to your computer and use it in GitHub Desktop.
Use react-navigation 4.x with mobx

NAVIGATION OPTIONS

export const StackNavigationOptions = (params = {}) => {
  let { headerStyle, headerTitleStyle, ...others } = params

  if (!headerStyle) headerStyle = {}
  if (!headerTitleStyle) headerTitleStyle = {}

  return {
    headerTransitionPreset: 'uikit',
    headerStyle: {
      backgroundColor: 'black',
      borderBottomColor: 'transparent',
      shadowOpacity: 0,
      shadowOffset: {
        height: 0
      },
      shadowRadius: 0,
      elevation: 0,
      ...headerStyle
    },
    headerTintColor: 'white',
    headerTitleStyle: {
      color: 'white',
      textAlign: 'center',
      fontSize: 20,
      fontWeight: 'bold',
      backgroundColor: 'transparent',
      fontFamily: Config.fontFamily,
      ...headerTitleStyle
    },
    headerBackTitle: null,
    headerBackImage: <IonIcon testID='leftIcon'
      style={styles.leftIcon}
      name={'md-arrow-back'}
    />,
    transparentCard: true,
    ...others
  }
}

export const getChildComponentNavigationOptions = navigation => {
  let currentNav = navigation
  if (!navigation.router) {
    currentNav = navigation.dangerouslyGetParent()
  }

  let options = null
  if (currentNav && currentNav.router) {
    const component = currentNav.router.getComponentForState(currentNav.state)

    if (component && component.wrappedComponent && component.wrappedComponent.navigationOptions) {
      if (typeof component.wrappedComponent.navigationOptions === 'function') {
        options = component.wrappedComponent.navigationOptions({
          navigation: {
            ...navigation,
            state: navigation.state
          }
        })
      } else {
        options = {
          ...component.wrappedComponent.navigationOptions,
          state: navigation.state
        }
      }
    } else if (component && component.navigationOptions) {
      if (typeof component.navigationOptions === 'function') {
        options = component.navigationOptions({
          navigation: {
            ...navigation,
            state: navigation.state
          }
        })
      } else {
        options = {
          ...component.navigationOptions,
          state: navigation.state
        }
      } 
    }
  }

  if (options && options.useDrawer) {
    options.headerLeft =
      <TouchableOpacity
        style={styles.btnMenu}
        onPress={() => {
          if (navigation.openDrawer) navigation.openDrawer()
        }}
      >
        <IonIcon
          testID='drawer-menu'
          style={styles.leftIcon}
          name={'md-menu'}
        />
      </TouchableOpacity>
  }

  return options
}

Use in route config

defaultNavigationOptions: ({ navigation, screenProps }) => {
      return StackNavigationOptions(getChildComponentNavigationOptions(navigation, screenProps) || {})
    },

Define in injected screen for overriding

@inject("store")
@observer
class Map extends Component {
....
}


Map.wrappedComponent.navigationOptions = ({ navigation }) => {
  return {
    headerTitle: 'MAP',
    useDrawer: true
  }
}

export default Map

Define in normal screen for overriding

class Screen extends Component {
....
}

Screen.navigationOptions = ({ navigation }) => {
  return {
    title: 'Me'
  }
}

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