Andrei Olar
Andrei Olar

Reputation: 2358

How to conditionally display drawerLabel within a DrawerNavigator

I recently added a new screen to the app and this screen needs to only be accessed by specific kind of users who are logged in.

class DemoScreen extends Component {
  static navigationOptions = {
    title: 'Title',
    drawerLabel: ({ tintColor, focused }) => {
      return (
        <MainMenuItem
          textKey={TEXTKEY}
          iconName="cellphone-settings"
          focused={focused}
          tintColor={tintColor}
        />
      );
    }
  };
// Skipping rest of the code
}

This component is connected to the redux store, so it has access to the users information. But this.props.<FIELD> cannot be accessed inside the navigationOptions.

My routes look like this

const MainMenu = DrawerNavigator(
  {
    // Other screens here
    Demo: { screen: DemoScreen },
  },
  {
    drawerWidth: 250,
    drawerPosition: 'left',
    contentComponent: MenuDrawerContent,
    contentOptions: drawerContentOptions
  }
);

export const Routes = {
  // Other routes here
  Main: {
    screen: MainMenu,
    navigationOptions: {
      gesturesEnabled: false
    }
  }
};

What I want is to display DemoScreen MainManuItem only to a specific type of logged in user. How do I accomplish that? Where should that logic reside?

Thanks.

Upvotes: 1

Views: 1352

Answers (2)

Andrei Olar
Andrei Olar

Reputation: 2358

I managed to solve this by moving the navigationOptions from the screen to the Routes. It looks like this now

const MainMenu = DrawerNavigator(
  {
    // Other screens here
    Demo: { 
      screen: DemoScreen,
      navigationOptions: {
        title: 'Title',
        drawerLabel: ({ tintColor, focused }) => {
          const id = store.getState().field;
          const valid = [1234, 2345];
          if (!valid.includes(id)) {
            return null;
          }

          return (
            <MainMenuItem
              textKey={TEXT}
              iconName="cellphone-settings"
              focused={focused}
              tintColor={tintColor}
           />
          );
        }
      }
    },
  },
  {
    drawerWidth: 250,
    drawerPosition: 'left',
    contentComponent: MenuDrawerContent,
    contentOptions: drawerContentOptions
  }
);

export const Routes = {
  // Other routes here
  Main: {
    screen: MainMenu,
    navigationOptions: {
      gesturesEnabled: false
    }
  }
};

I'm not sure if this is the best approach, but it works.

I do have some eslint warnings which I don't know how to solve. Those are:

1. component definition is missing display name

2. 'focused' and 'tintColor' is missing in props validation

Both warnings are on this line: drawerLabel: ({ tintColor, focused }) => {. For the moment I've ignored them, but does someone know how to fix them for this case?

Upvotes: 2

Chris Cousins
Chris Cousins

Reputation: 1912

Add a componentWillMount function (that receives props) to your DemoScreen. In that function, read from props and then depending on the type of user, you can create your navigationOptions in the object's state instead. You can pass in the "gesturesEnabled" into the component still - it will come in as props also into the componentWillMount function.

Upvotes: 0

Related Questions