2 years ago

#62634

test-img

Dieguinho

React navigation migration from v3 to v6

I've been assigned to a project where we need to upgrade react navigation from version 3 to version 6. Looking at the code I've found some strage stuff (or at least I think they are strange), the project consists of a Switch Navigator with two Stak Navigators inside like this:

const NavigatorOne = createStackNavigator(
  {
    NavOneScreenOne: {screen: NavOneScreenOne},
    NavOneScreenTwo: {screen: NavOneScreenTwo},
    NavOneScreenThree: {screen: NavOneScreenThree},
    NavOneScreenFour: {screen: NavOneScreenFour}
  },
  {
    headerMode: 'none',
    navigationOptions: {
      header: null,
    },
    defaultNavigationOptions: {
      gesturesEnabled: false,
    },
  }
);

const NavigatorTwo = createStackNavigator(
  {
    NavTwoScreenOne: {screen: NavTwoScreenOne},
    NavTwoScreenTwo: {screen: NavTwoScreenTwo},
    NavTwoScreenThree: {screen: NavTwoScreenThree},
    NavTwoScreenFour: {screen: NavTwoScreenFour}
  },
  {
    headerMode: 'float',
    navigationOptions: {},
    defaultNavigationOptions: {
      header: <Header />,
      gesturesEnabled: false,
    },
  }
);

export default createAppContainer(
  createSwitchNavigator(
    {
      App: NavigatorOne,
      Visits: NavigatorTwo,
      Login: PageLogin,
    },
    {
      initialRouteName: 'Login',
      backBehavior: 'none',
    }
  )
);

Then I have an AppNavigatorContainer, like this one:

const AppNavigatorContainer = ({ setNavigator }: { setNavigator: (n: NavigationContainerComponent) => void }) => {
  const dispatch = useDispatch();

  return (
    <AppNavigator
      ref={(navigatorRef) => {
        NavigationService.setTopLevelNavigator(navigatorRef);
        setNavigator(navigatorRef);
      }}
      onNavigationStateChange={(_prevState, currentState) => dispatch(setCurrentRoute(NavigationService.getActiveRouteName(currentState)))}
    />
  );
};

and the App file like this:

  const [navigator, setNavigator] = useState(null);
  return (
    <Provider store={ReduxConf.store}>
      <PersistGate loading={null} persistor={ReduxConf.persistor}>
        <ReduxNetworkProvider pingInterval={20000}>
          <Root>
            <StyledView>
              <StatusBar hidden />
              <Header />
              <AppNavigatorContainer setNavigator={setNavigator} />
              <Toolbar />
              <Menu />
              ...
            </StyledView>
            ...
          </Root>
        </ReduxNetworkProvider>
      </PersistGate>
    </Provider>
  );

So basically its saving a reference to the AppNavigator inside a global file (NavigationService) so that it can be accessed everywhere, including Menu and Toolbar which aren't nested inside AppNavigatorContainer. Toolbar is a toolbar set at the bottom of the screen which changes buttons according if you are in the first or second stack.

As I see it, toolbar should be built using two TabNavigators (each one with its set of buttons/tabs) inside a StackNavigator, and Menu should be a DrawerNavigator (don't know if in version 3 of react navigation had these stacks), and should be nested inside the SwitchNavigator (in version 6 theres no Switch but the concept remains the same).

Is this a poorly written navigation structure? it feels it breaks many good coding rules... (the current structure of the project)

react-native

react-navigation

react-navigation-v6

0 Answers

Your Answer

Accepted video resources