Reputation: 6158
To add an extra Drawer button that doesn't link to a route above or below a button in DrawerItemList
is as easy as doing:
<Drawer.Navigator initialRouteName="Home" drawerContent={props => {
return (
<DrawerContentScrollView {...props}>
<DrawerItemList {...props} />
<DrawerItem label="Logout" onPress={() => props.navigation.navigate("Login")} />
</DrawerContentScrollView>
)
}}>
<Drawer.Screen name="Home" component={Home}/>
<Drawer.Screen name="About" component={About} />
</Drawer.Navigator>
But now I need to add a custom button (like the Logout one, with a custom onPress
that doesn't just go to a route, but navigates to Home and calls a couple of functions) between the Home
and About
buttons.
So my end button result with regards to the buttons on the Drawer should be:
-- Home
-- Custom
-- About
-- Logout
I'd need to somehow break up DrawerItemList
but not sure how.
Any ideas how I can achieve this?
Snack can be found here
(Using react-navigation > v5)
Upvotes: 4
Views: 2596
Reputation: 4673
The easiest way to achieve this, is just to not use the DrawerItemList
at all.
Simple example without any styling (see Snack):
<Drawer.Navigator
initialRouteName="Home"
drawerContent={(props) => {
return (
<DrawerContentScrollView {...props}>
<Button title="Home"onPress={() => props.navigation.navigate("Home")} />
<Button title="Custom" onPress={() => console.log('Custom Logic')} />
<Button title="About" onPress={() => props.navigation.navigate("About")} />
<Button title="Logout" onPress={() => console.log('CUSTOM LOGOUT FUNCTION')} />
</DrawerContentScrollView>
);
}}>
<Drawer.Screen name="Home" component={PlaceholderPage} />
<Drawer.Screen name="About" component={PlaceholderPage} />
</Drawer.Navigator>
Upvotes: 2
Reputation: 1473
I did it in my case.
Add this to drawer items
<DrawerItem
{...props}
onPress={()=> {
navigation.navigate('home');
//. do other things
}}
label={"Custome"}
icon={() => <Icon name="custome" size={25} color={colors.jasmine} />}
style={props.itemStyle}
/>
Upvotes: 0
Reputation: 16334
To begin with , the code of DrawerItemList doesnt allow anything else except for screens to be there.
But its just another component that you have to pass.
So the easiest way to handle this would be to create your own version of DrawerItemList using the source code and have the option to pass a custom onPress function.
The custom component would look like this, I've commented the places that i modified.
import * as React from 'react';
import {
CommonActions,
DrawerActions,
DrawerNavigationState,
ParamListBase,
useLinkBuilder,
} from '@react-navigation/native';
import { DrawerItem } from '@react-navigation/drawer';
export default function CustomDrawerList({
state,
navigation,
descriptors,
activeTintColor,
inactiveTintColor,
activeBackgroundColor,
inactiveBackgroundColor,
itemStyle,
labelStyle,
}: Props) {
const buildLink = useLinkBuilder();
return state.routes.map((route, i) => {
const focused = i === state.index;
//Access the custom onPress that is passed as an option
const { title, drawerLabel, drawerIcon, onPress } = descriptors[route.key].options;
return (
<DrawerItem
key={route.key}
label={
drawerLabel !== undefined
? drawerLabel
: title !== undefined
? title
: route.name
}
icon={drawerIcon}
focused={focused}
activeTintColor={activeTintColor}
inactiveTintColor={inactiveTintColor}
activeBackgroundColor={activeBackgroundColor}
inactiveBackgroundColor={inactiveBackgroundColor}
labelStyle={labelStyle}
style={itemStyle}
to={buildLink(route.name, route.params)}
onPress={
//if onPress is available use that or call the usual navigation dispatch
// i also passed the navigation so that we can use it in our custom calls
onPress
? () => onPress(navigation)
: () => {
navigation.dispatch({
...(focused
? DrawerActions.closeDrawer()
: CommonActions.navigate(route.name)),
target: state.key,
});
}
}
/>
);
});
}
And the drawer would look like this, we pass the onPress as an option
<Drawer.Navigator
initialRouteName="Home"
drawerContent={(props) => {
return (
<DrawerContentScrollView {...props}>
<CustomDrawerList {...props} />
</DrawerContentScrollView>
);
}}>
<Drawer.Screen name="Home" component={PlaceholderPage} />
<Drawer.Screen name="Custom" component={PlaceholderPage} options={{
onPress:()=>alert(123)
}}/>
<Drawer.Screen name="About" component={PlaceholderPage} />
</Drawer.Navigator>
You can check the snack here https://snack.expo.io/@guruparan/custom-button-in-drawer
Upvotes: 5