Skip to content
This repository has been archived by the owner on Aug 8, 2024. It is now read-only.

Discuss cases where shallow navigation options are difficult to use #44

Open
brentvatne opened this issue May 8, 2018 · 11 comments
Open

Comments

@brentvatne
Copy link
Member

brentvatne commented May 8, 2018

Please take into account the justification in https://github.com/react-navigation/rfcs/blob/master/text/0005-shallow-navigation-options.md when discussing this

@iRoachie
Copy link

iRoachie commented Jun 4, 2018

The solution provided only works for navigators that are direct descendants of the TabNavigator. For nested navigators navigation.state does not change.

// Main Tab navigator
export default createBottomTabNavigator(
  {
    Posts: {
      screen: Posts, // Posts.jsx
      navigationOptions: ({ navigation }: any) => {
        let tabBarVisible = true

        if (navigation.state.index > 0) {
          tabBarVisible = false
        }

        return {
          tabBarVisible,
      },
    },
    Lecturers: {
      screen: Lecturers, // Lecturers.jsx
      navigationOptions: ({ navigation }: any) => {
        let tabBarVisible = true

        if (navigation.state.index > 0) {
          tabBarVisible = false
        }

        return {
          tabBarVisible,
        },
    }
}
// Posts.jsx
export default createStackNavigator(
  {
    posts: {
      screen: Posts,
    },
    viewPost: {
      screen: ViewPost,
    },
    searchPosts: {
      screen: SearchPosts,
    },
  },
  {
    headerMode: 'screen',
  }
)

Posts.jsx works as expected since it's one level deep.

// Lecturers.jsx
const PushStack = createStackNavigator(
  {
    lecturers: {
      screen: Lecturers,
    },
    viewLecturer: {
      screen: ViewLecturer,
    },
    viewCourse: {
      screen: ViewCourse,
    },
  },
  {
    headerMode: 'screen',
  }
)

export default createStackNavigator(
  {
    Main: {
      screen: PushStack,
    },
    newReview: {
      screen: NewReview,
    },
    search: {
      screen: Search,
    },
  },
  {
    mode: 'modal',
  }
)

However Lecturers.jsx doesn't work because it has a nested stack.

Example video:
https://www.useloom.com/share/8278cf55d92a452d9818df5e132d0ac7

@iRoachie
Copy link

iRoachie commented Jun 4, 2018

An ideal way I can think of accomplishing this is to introduce a tabBarHiddenOn property that would contain all the screens by key, that the tabBar should be hidden on. By default tabBarVisible would be set to true. This would be a far cleaner solution than writing logic based on the index.

In the above example it could look like this:

export default createBottomTabNavigator(
{
    Posts: {
      screen: Posts,
      navigationOptions: {
        tabBarHiddenOn: [ 'viewPost', 'searchPosts' ]
      }
    }
}

@ravirajn22
Copy link

ravirajn22 commented Jun 4, 2018

@brentvatne can you look into this issue. My app update is pending due to this issue. Your current update to this navigationOptions seems not at all intuitive ones navigators start getting nested.

@leethree
Copy link

leethree commented Jul 4, 2018

I read the documentation for "A stack contains a tab navigator and you want to set the title on the stack header". The suggested solution works for setting header titles. But it quickly breaks down when we need control things more complicated than the title.

Our problem with the approach is that the navigator needs to know about how the header should behave with each screen. We have some button controls in the header that interacts with the content of the screen. It makes more sense to have the button logic in the navigationOptions of each screen than in the navigator.

See react-navigation/react-navigation.github.io#152 (comment) where I explained the use case before.

@ravirajn22
Copy link

@leethree yes even I faced the same issue, it just doesn't feel right to put the navigationOptions for a particular screen in the navigator and also it does not work when having buttons which setParams. But in those cases, they are recommending to go with the first option of putting each Tab screen as a separate Stack and control the header for these Stacks individually. But I don't know if this is the right way to go.

@brentvatne
Copy link
Member Author

brentvatne commented Jul 4, 2018

can people create some snacks with examples of their problems please? https://snack.expo.io

@iRoachie
Copy link

iRoachie commented Jul 5, 2018

@brentvatne Here's the snack for my scenario above https://snack.expo.io/@roach_iam/react-navigation-tabs-nested-stacks. As you can see the tabBar doesn't hide for the Lecturers stack.

@ravirajn22
Copy link

ravirajn22 commented Oct 2, 2018

@leethree and @iRoachie how did you solve this problem? I am still waiting for a fix to this problem. @brentvatne I think u should look into this issue. What used to be a normal solution in v1.0, seems now like a huge code mess and still, I can't make it work in v2.0.

@iRoachie
Copy link

iRoachie commented Oct 2, 2018

@ravirajn22 I didn’t actually solve it per say. I used a workaround in that I moved all my modals into one navigator at the root of my app.

@leethree
Copy link

leethree commented Oct 2, 2018

@ravirajn22 No we haven't found a clean solution for this, so we are still using v1.0 🤷‍♂️

@2diegoduque
Copy link

The only thing that worked for me

const homeScreenStack = createStackNavigator({
  Home: {
    screen: Home,
    navigationOptions: ({ navigation }) => ({
      title: "Home"
    })
  },
  Comments: {
    screen: Comments,
    navigationOptions: ({ navigation }) => ({
      title: "Comments"
    })
  }
});

homeScreenStack.navigationOptions = ({ navigation }) => {
  let tabBarVisible = true;
  for (let i = 0; i < navigation.state.routes.length; i++) {
    if (navigation.state.routes[i].routeName == "Comments") {
      tabBarVisible = false;
    }
  }

  return {
    tabBarVisible
  };
};

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants