#reactjs #react-native #react-navigation
#reactjs #react-native #react-навигация
Вопрос:
Добавить дополнительную кнопку ящика, которая не связана с маршрутом выше или ниже кнопки DrawerItemList
, так же просто, как сделать:
<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>
Но теперь мне нужно добавить пользовательскую кнопку (например, для выхода из системы, с пользовательской onPress
, которая не просто переходит к маршруту, но переходит к дому и вызывает пару функций) между кнопками Home
и About
.
Итак, мой конечный результат кнопки в отношении кнопок на ящике должен быть:
— Главная
— Пользовательский
— О
— Выход из системы
Мне нужно было бы как-то расстаться DrawerItemList
, но не уверен, как.
Есть идеи, как я могу этого добиться?
Закуску можно найти здесь
(Используя react-navigation> v5)
Ответ №1:
Начнем с того, что код DrawerItemList не допускает присутствия ничего другого, кроме экранов.
Но это просто еще один компонент, который вы должны передать.
Таким образом, самый простой способ справиться с этим — создать свою собственную версию DrawerItemList с использованием исходного кода и иметь возможность передавать пользовательскую функцию onPress .
Пользовательский компонент будет выглядеть так, я прокомментировал места, которые я изменил.
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,
});
}
}
/>
);
});
}
И ящик будет выглядеть так, мы передаем onPress в качестве опции
<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>
Вы можете проверить закуску здесь
https://snack.expo.io/@guruparan/custom-button-in-drawer
Комментарии:
1. Я решил использовать это решение. Это не идеально, если они когда-либо будут обновляться
DrawerList
в будущих версиях (вероятно), но это единственный способ с ограниченным в настоящее время API и отлично подходит для моего варианта использования. Спасибо!2. Да, лучше посмотрите, есть ли серьезные обновления, кроме того, что это окажет минимальное влияние на drawerlist
Ответ №2:
Самый простой способ добиться этого — просто не использовать DrawerItemList
вообще.
Простой пример без какого-либо оформления (см. 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>
Ответ №3:
Я сделал это в моем случае.
Добавьте это в элементы ящика
<DrawerItem
{...props}
onPress={()=> {
navigation.navigate('home');
//. do other things
}}
label={"Custome"}
icon={() => <Icon name="custome" size={25} color={colors.jasmine} />}
style={props.itemStyle}
/>