The goal
I'm trying to achieve a screen that looks like this. There are two menus, one is the burger menu created by createDrawerNavigator
from react-navigation (top left corner).
The other menu is the bottom button created by createBottomTabNavigator
.
Yes having two menus isn't a good UI choice, but that's my company's choice .. Moreover these menus share at least one entry (homepage).
What did I try
This stackoverflow was pretty close of the awaited result, but I can't figure out how to display the burger menu and not a simple view like the post does.
I tried multiple hierarchy structures without success to accomplish exactly the goal.
So I was out of ideas and I decided to accomplish the bottom menu on my own. It seems to work well, but some routes aren't defined so I can't navigate to them (like cart and search on my screen)
It seems that react-navigation uses its component to define the routes.
The question
How can I add routes to the navigation system in order to be able to navigate to them?
I tried :
Specifying an initialState to the
<NavigationContainer>
but it doesn't seem to work.Created a custom router to overwrite the
getInitialState
method, but I can't figure out how to use my custom router after that!
Any help will be greatly appreciated
Edit:
The navigation code
// src/menu/burger/drawer.js
import { createDrawerNavigator } from '@react-navigation/drawer';
import { useTranslation } from 'react-i18next';
import Ionicons from '@expo/vector-icons/Ionicons';
import React from 'react';
import Account from '../../pages/account';
import Brands from '../../pages/brands';
import Cart from '../../pages/cart';
import Homepage from '../../pages/homepage';
import {
ACCOUNT,
BRANDS,
CART,
HOMEPAGE,
} from '../../pages/pageIdentifiers';
const Drawer = createDrawerNavigator();
const renderMenuIcon = (iconName, size, focused) => (
<Ionicons
name={iconName}
size={size}
color={focused ? '#7cc' : '#ccc'}
/>
);
// This component render the items of the burger menu displayed in the top left corner
export default function MenuDrawer() {
const { t } = useTranslation();
return (
<Drawer.Navigator
initialRouteName={HOMEPAGE}
>
<Drawer.Screen
name={HOMEPAGE}
component={Homepage}
options={{
title: t('menu.item.homepage'),
drawerIcon: ({ focused, size }) => renderMenuIcon('md-home', size, focused),
}}
/>
<Drawer.Screen
name={CART}
component={Cart}
options={{
title: t('menu.item.cart'),
drawerIcon: ({ focused, size }) => renderMenuIcon('cart-outline', size, focused),
}}
/>
<Drawer.Screen
name={ACCOUNT}
component={Account}
options={{
title: t('menu.item.account'),
drawerIcon: ({ focused, size }) => renderMenuIcon('person-outline', size, focused),
}}
/>
<Drawer.Screen
name={BRANDS}
component={Brands}
options={{
title: t('menu.item.brands'),
drawerIcon: ({ focused, size }) => renderMenuIcon('basket-outline', size, focused),
}}
/>
</Drawer.Navigator>
);
}
// App.js
export default function App() {
return (
<NavigationContainer>
<Stack.Navigator>
<MenuDrawer />
<BottomTabsMenu />
</Stack.Navigator>
</NavigationContainer>
);
}
// src/menu/bottomTabs/drawer.js
// We can't use 2 menus with 2 differents navigators on the same view.
// So let's handle the click on tabs ourselves
export default function BottomTabsMenu() {
const [activeTab, setActiveTab] = useState(HOMEPAGE);
const navigation = useNavigation();
// useEffect(() => {
// const subscription = navigation.addListener('focus', (data) => {
// console.log(data);
// });
// return subscription;
// }, [navigation]);
// This function crash when the route id is not known by react-navigation, well logic
const onMenuPress = (id) => {
navigation.navigate(id);
setActiveTab(id);
};
return (
<View style={styles.container}>
{bottomMenuItems.map(
(menuItem) => (
<View
key={`view-${menuItem.id}`}
style={styles.item}
>
<MenuItem
key={`menu-${menuItem.id}`}
isFocus={menuItem.id === activeTab}
onPress={(id) => onMenuPress(id)}
configuration={menuItem}
/>
</View>
)
)}
</View>
);
}