rfcs icon indicating copy to clipboard operation
rfcs copied to clipboard

Alternative API for defining navigators

Open brentvatne opened this issue 5 years ago • 12 comments

I've noticed that people have had a hard time grasping how nesting navigators works in React Navigation, and part of that might be due to the relatively flat appearance of defining navigators with functions and then passing the navigators in as screens to others.

It might be good to provide a library that lets people use a JSX oriented API that gives a more natural sense of nesting. A proof of concept of this can be found here: https://snack.expo.io/@notbrent/dsl

See:

// Notice in this example that the modal is inside of the tabs -- the tabs UI
// appears on top of the modal profile stack
const Navigation = createAppContainer(
  <BottomTabs>
    <Route name="Home" path="/" screen={HomeScreen} />
    <Route name="Profile" path="/profile">
      <Stack mode="modal">
        <Route
          name="ProfileShow"
          path="/"
          screen={ProfileScreen}
          navigationOptions={{ title: 'Profile' }}
        />
        <Route name="Settings" path="/settings">
          <Stack navigationOptions={{ header: null }}>
            <Route
              name="SettingsShow"
              path="/"
              screen={SettingsScreen}
              navigationOptions={{ title: 'Settings' }}
            />
            <Route
              name="About"
              path="/"
              screen={AboutScreen}
              navigationOptions={{ title: 'About' }}
            />
          </Stack>
        </Route>
      </Stack>
    </Route>
  </BottomTabs>
);

And compare it with

// Here we put the modal stack at the root so the stack ui appears on top of
// the tabs rather than underneat the tabs
const AlternativeNavigation = createAppContainer(
  <Stack mode="modal" headerMode="none">
    <Route name="Tabs">
      <BottomTabs>
        <Route name="Home" path="/" screen={HomeScreen} />
        <Route name="Profile" path="/profile">
          <Stack>
            <Route
              name="ProfileShow"
              path="/"
              screen={ProfileScreen}
              navigationOptions={{ title: 'Profile' }}
            />
          </Stack>
        </Route>
      </BottomTabs>
    </Route>
    <Route name="Settings" path="/settings">
      <Stack>
        <Route
          name="SettingsShow"
          path="/"
          screen={SettingsScreen}
          navigationOptions={{ title: 'Settings' }}
        />
        <Route
          name="About"
          path="/"
          screen={AboutScreen}
          navigationOptions={{ title: 'About' }}
        />
      </Stack>
    </Route>
  </Stack>
);

at a glance it may be easier to understand than the alternative of using createXNavigator

brentvatne avatar Apr 18 '19 22:04 brentvatne