Creating a TabNavigator with dynamic tabs
Yessssss! I think I found a way. The solution probably isn't following the design pattern, but this is what I came up with:
export default class DynamicTabBar extends React.Component {
static router = TabRouter({
Start: {
screen: UserStackNavigator,
navigationOptions: {
tabBarIcon: (<Icon
type="font-awesome"
name="users"
color="#dddddd"
size={20}
/>),
},
},
...Account.User.CanEnter ? {
ConditionalTab: {
screen: ConditionalScreen,
navigationOptions: {
tabBarIcon: (<Icon
type="font-awesome"
name="recycle"
color="#dddddd"
size={20}
/>),
},
}} : {},
Settings: {
screen: Settings,
navigationOptions: {
tabBarIcon: (<Icon
type="font-awesome"
name="cog"
color="#dddddd"
/>),
}
}
},{
...TabNavigator.Presets.AndroidTopTabs,
tabBarPosition: "bottom",
tabBarOptions: {
activeTintColor: '#eaeb65',
showIcon: true,
showLabel: false,
style: { backgroundColor: '#333' },
}
});
constructor(props) {
super(props);
}
render() {
const tabs = TabNavigator({
Start: {
screen: UserStackNavigator,
navigationOptions: {
tabBarIcon: (<Icon
type="font-awesome"
name="users"
color="#dddddd"
size={20}
/>),
},
},
...Account.User.CanEnter ? {
ConditionalTab: {
screen: ConditionalScreen,
navigationOptions: {
tabBarIcon: (<Icon
type="font-awesome"
name="recycle"
color="#dddddd"
size={20}
/>),
},
}} : {},
Settings: {
screen: Settings,
navigationOptions: {
tabBarIcon: (<Icon
type="font-awesome"
name="cog"
color="#dddddd"
/>),
}
}
},{
...TabNavigator.Presets.AndroidTopTabs,
tabBarPosition: "bottom",
tabBarOptions: {
activeTintColor: '#eaeb65',
showIcon: true,
showLabel: false,
style: { backgroundColor: '#333' },
}
});
return <Tabs navigation={this.props.navigation} />;
}
}
The router is assigned in a static way and is built dynamically at runtime.
I know this is old, but AFAICT there is no blessed way to do this still, in 2019. Here is the solution I came up with, and I think it's fairly simple.
Basically, I specify a custom tabBarComponent
with a custom getButtonComponent
method that either renders the button or not based on the current user. If the user shouldn't see the nav item, then it renders an empty view, which has the effect of hiding the navigation item.
import { createBottomTabNavigator } from 'react-navigation'
import { BottomTabBar } from 'react-navigation-tabs'
class TabBar extends React.Component {
render() {
return (
<BottomTabBar
{...this.props}
getButtonComponent={this.getButtonComponent}
/>
)
}
getButtonComponent({ route }) {
if (route.key === 'Other') {
return () => <View /> // a view that doesn't render its children
} else {
return null // use the default nav button component
}
}
}
const AppNav = createBottomTabNavigator(
{
Home: HomeStack,
Other: OtherScreen,
},
{
tabBarComponent: TabBar,
}
)