How can I place an icon before Home and Notifications of the Drawer.Screen - react-native

I am learning how to use React Navigation.
How can I place an icon before Home and Notifications of the Drawer.Screen
import * as React from 'react';
import { Button, View } from 'react-native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
onPress={() => navigation.navigate('Notifications')}
title="Go to notifications"
/>
</View>
);
}
function NotificationsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button onPress={() => navigation.goBack()} title="Go back home" />
</View>
);
}
const Drawer = createDrawerNavigator();
export default function App() {
return (
<NavigationContainer>
<Drawer.Navigator initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Notifications" component={NotificationsScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
}
And how do I do so that when entering the view add a tab screen

You can create a custom component and render it in your drawer.
Here the ButtonList is a custom component that you pass it to drawerContent. And you can create a list in the ButtonList and put the icon between Home and Notification easily.
<ActionDrawer.Navigator
drawerType="back"
drawerPosition="right"
drawerContent={(props) => <ButtonList {...props} />}
drawerStyle={{
width: wp('65'),
}}
>

Related

What is the proper way to have only one header with Open Drawer and Back button?

What I need is a single header with a back button on StackScreen2 and a toggle drawer button in StackScreen1.
I apologise for my poor writing and English.
import * as React from 'react';
import { Button, View, Text } from 'react-native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
const Stack = createNativeStackNavigator();
function StackScreen1({ navigation }) {
return (
<View>
<Text>StackScreen1</Text>
<Button title="Go To StackScreen2" onPress={() => navigation.navigate("StackScreen2")} />
</View>
)
}
function StackScreen2() {
return (
<View>
<Text>StackScreen2</Text>
</View>
)
}
function DrawerScreen1() {
return (
<Stack.Navigator>
<Stack.Screen name="StackScreen1" component={StackScreen1} />
<Stack.Screen name="StackScreen2" component={StackScreen2} />
</Stack.Navigator>
)
}
function DrawerScreen2() {
return (
<View>
<Text>DrawerScreen2</Text>
</View>
)
}
const Drawer = createDrawerNavigator();
export default function Test3() {
return (
<NavigationContainer>
<Drawer.Navigator>
<Drawer.Screen name="DrawerScreen1" component={DrawerScreen1} />
<Drawer.Screen name="DrawerScreen2" component={DrawerScreen2} />
</Drawer.Navigator>
</NavigationContainer>
);
}
StackScreen1
StackScreen2
I tried hiding drawer header but then I don't have toggle drawer button anywhere.
Check below code for drawer navigation:
import * as React from 'react';
import { Button, View } from 'react-native';
import { createDrawerNavigator } from '#react-navigation/drawer';
import { NavigationContainer } from '#react-navigation/native';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
onPress={() => navigation.navigate('Notifications')}
title="Go to notifications"
/>
</View>
);
}
function NotificationsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button onPress={() => navigation.goBack()} title="Go back home" />
</View>
);
}
const Drawer = createDrawerNavigator();
export default function App() {
return (
<NavigationContainer>
<Drawer.Navigator useLegacyImplementation initialRouteName="Home">
<Drawer.Screen name="Home" component={HomeScreen} />
<Drawer.Screen name="Notifications" component={NotificationsScreen} />
</Drawer.Navigator>
</NavigationContainer>
);
}
You can check more about drawer here.
May be this will help you!
import * as React from 'react';
import { Ionicons, FontAwesome } from '#expo/vector-icons';
import { Button, View, Text, Pressable,Image } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
import { createDrawerNavigator } from '#react-navigation/drawer';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Home Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('SettingsScreen')}
/>
</View>
);
}
function DetailsScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>Details Screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.goBack()}
/>
</View>
);
}
const Drawer = createDrawerNavigator();
function MyDrawer() {
return (
<Drawer.Navigator
useLegacyImplementation
// screenOptions={{
// drawerLabelStyle: { fontSize: 17, color: '#000',marginLeft:-30 }
// }}
>
<Drawer.Screen
name="HomeScreen"
component={DetailsScreen}
screenOptions={{
headerShown: false,
}}
/>
</Drawer.Navigator>
);
}
function MyTabs() {
return (
<Tab.Navigator>
<Tab.Screen
name="SettingsScreen"
component={MyDrawer}
options={{
headerShown: false,
tabBarIcon: ({ color, size }) => (
<Ionicons name="md-home" size={24} color={'#eee'} />
),
tabBarStyle: { position: 'absolute' },
tabBarActiveTintColor: '#eee',
tabBarInactiveTintColor: '#eee',
}}
/>
<Tab.Screen
name="DetailsScreen"
component={DetailsScreen}
options={{
headerShown: false,
tabBarIcon: ({ color, size }) => (
<Image source={{uri:"https://encrypted-tbn0.gstatic.com/images?q=tbn:ANd9GcTUAN0zLcvLFjdaYN1dBRSKoIuJndRW6VuX85w2yzEzxvTwO3B0Y_gv1x8kVDISNKJEbq0&usqp=CAU"}}
style={{width:24,height:24,borderRadius:24}} />
),
tabBarStyle: { position: 'absolute' },
tabBarActiveTintColor: '#eee',
tabBarInactiveTintColor: '#eee',
}}
/>
</Tab.Navigator>
);
}
function SettingsScreen() {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Text>2</Text>
</View>
);
}
const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();
function App() {
return (
<NavigationContainer>
<Stack.Navigator initialRouteName="HomeScreen">
<Stack.Screen
name="HomeScreen"
component={HomeScreen}
options={{ headerShown: false }}
/>
<Stack.Screen
name="SettingsScreen"
component={MyTabs}
options={{ headerShown: false }}
/>
</Stack.Navigator>
</NavigationContainer>
);
}
export default App;

React Native Navigation Test sample

So, I have been playing around with navigation in React Native and wanted to test something out with it. So I have generally been working with a stack navigation and have built it and works just fine. What I was testing around with was using navigate like I would in react.js and be able to just use that to move between components.
App.tsx
import { StatusBar } from 'expo-status-bar';
import { StyleSheet, Text, View } from 'react-native';
import Main from "./screens/main";
import { NavigationContainer } from "#react-navigation/native";
export default function App() {
return (
<View style={styles.container}>
{/*<NavigationContainer>*/}
<Main />
{/*</NavigationContainer>*/}
</View>
);
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
alignItems: 'center',
justifyContent: 'center',
},
});
Main.tsx
import React, { FC } from "react";
import { Button, View, Text } from "react-native";
import Home from "./home";
import { useNavigation } from "#react-navigation/native";
const App : FC = () => {
const navigation = useNavigation();
return(
<View>
<Text>This is just a holding screen</Text>
<Button title="Home" onPress={()=> navigation.navigate(Home)}/>
</View>
)
}
export default App;
Home.tsx
import React from "react";
import { View, Text} from "react-native";
import Main from "./main"
export default function App(){
return(
<View>
<Text>
Test this
</Text>
</View>
)
}
Not sure if this is even possible or just best to use the stack navigation? To me this is more similar to native development where I am on one screen and just call the screen that I want to move to.
I also was looking at the docs for this here.
https://reactnavigation.org/docs/navigation-actions/#navigate
React Navigation requires defining and registering all your navigation routes before navigating to them.
A simple example of stack navigation with multiple screens:
import * as React from 'react';
import { Button, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
title="Go to Profile"
onPress={() => navigation.navigate('Profile')}
/>
</View>
);
}
function ProfileScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
title="Go to Notifications"
onPress={() => navigation.navigate('Notifications')}
/>
<Button title="Go back" onPress={() => navigation.goBack()} />
</View>
);
}
function NotificationsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button
title="Go to Settings"
onPress={() => navigation.navigate('Settings')}
/>
<Button title="Go back" onPress={() => navigation.goBack()} />
</View>
);
}
function SettingsScreen({ navigation }) {
return (
<View style={{ flex: 1, alignItems: 'center', justifyContent: 'center' }}>
<Button title="Go back" onPress={() => navigation.goBack()} />
</View>
);
}
const Stack = createStackNavigator();
function MyStack() {
return (
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Notifications" component={NotificationsScreen} />
<Stack.Screen name="Profile" component={ProfileScreen} />
<Stack.Screen name="Settings" component={SettingsScreen} />
</Stack.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<MyStack />
</NavigationContainer>
);
}
In-depth docs - https://reactnavigation.org/docs/stack-navigator/#api-definition
Working Demo - https://snack.expo.dev/#emmbyiringiro/d7224b

React Navigation V6 Bottom Tab Not Displaying

I'm following the guide here from React Navigation V6 and my component is not displaying as it is intended to. When I swap out createBottomTabNavigator with createMaterialTopTabNavigator I get my display. Can somebody help me figure out why the output is behaving this way? Photos are attached below the code. Thank you to anybody that can help!
Edit: React-Native-Web sometimes displays things incorrectly. When viewed on a phone it looks correct.
import * as React from 'react';
import { Button, Text, View } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createNativeStackNavigator } from '#react-navigation/native-stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
const Stack = createNativeStackNavigator();
const Tab = createBottomTabNavigator();
function FeedScreen() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Feed Screen!</Text>
</View>
);
}
function HomeScreen({ navigation }:any) {
return (
<View >
<Text>Home screen</Text>
<Button
title="Go to Profile"
onPress={() => navigation.navigate('Profile')}
/>
<Button
title="Go to Settings"
onPress={() => navigation.navigate('Settings')}
/>
</View>
);
}
function NotificationsScreen({ navigation }:any) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Notifications Screen</Text>
</View>
);
}
function ProfileScreen({ navigation }:any) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Profile Screen</Text>
<Button
title="Go to Settings"
onPress={() => navigation.navigate('Settings')}
/>
</View>
);
}
function SettingsScreen({ navigation }:any) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings screen</Text>
<Button
title="Go to tabs"
onPress={() => navigation.navigate('Home')}
/>
</View>
);
}
function BasicStack() {
return (
<Stack.Navigator>
<Stack.Screen
name="Home"
component={Home}
options={{ headerShown: true }}
/>
<Stack.Screen name="Profile" component={ProfileScreen} />
<Stack.Screen name="Settings" component={SettingsScreen} />
</Stack.Navigator>
)
}
function Home() {
return (
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeScreen} />
<Tab.Screen name="Feed" component={FeedScreen} />
<Tab.Screen name="Notifications" component={NotificationsScreen} />
</Tab.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<BasicStack/>
</NavigationContainer>
);
}
Output with createBottomTabNavigator
Output with createMaterialTopTabNavigator

ReactNative how to disable click on drawer menu item

the drawer menu setup is like below.
how can i disable click on first Drawer.Screen ?
it must show a single image!!
also how can i hide one element programmatically?
<Drawer.Navigator
initialRouteName="Feed"
drawerPosition="right"
drawerStyle={{
backgroundColor: '#c7c4b8',
width: 240,
}}
overlayColor="transparent">
<Drawer.Screen
name="Profile2"
component={Profile2}
options={{ drawerLabel: '', drawerIcon: ({ focused, size }) => (
<Image source={require('./images/3.jpg')} resizeMode={'cover'} style={{ width: '100%', height: 200 }} />)
}}
/>
<Drawer.Screen
name="Home"
component={Notifications}
options={{ drawerLabel: 'Feed' }}
/>
<Drawer.Screen
name="Routes"
component={Profile}
options={{ drawerLabel: 'Routes' }}
/>
</Drawer.Navigator>
For add header or whatever you want you should use drawerContent prop and there you can make your custom drawer or manipulate the existing one like in the example below.
For show/hide screen in a drawer programatically you can just use it with useState or pass a redux store and conditionally render it or not, remember that navigator its just a react component.
I let you a snack to check it online as well.
https://snack.expo.io/#anthowm/drawer-navigation-%7C-react-navigation
import * as React from 'react';
import {useState} from 'react';
import { View, Text, Image } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import {
createDrawerNavigator,
DrawerContentScrollView,
DrawerItemList,
DrawerItem,
} from '#react-navigation/drawer';
function Feed() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Feed Screen</Text>
</View>
);
}
function Article() {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Article Screen</Text>
</View>
);
}
function CustomDrawerContent(props) {
return (
<DrawerContentScrollView {...props}>
<Image source={{
uri: 'https://reactnative.dev/img/tiny_logo.png',
}} resizeMode={'cover'} style={{ width: '100%', height: 200 }} />
<DrawerItemList {...props} />
<DrawerItem
label="Hide Screen"
onPress={() => props.setShow(false)}
/>
</DrawerContentScrollView>
);
}
const Drawer = createDrawerNavigator();
function MyDrawer() {
const [show, setShow] = useState(true);
return (
<Drawer.Navigator drawerContent={props => <CustomDrawerContent setShow={setShow} {...props} />}>
<Drawer.Screen name="Feed" component={Feed} />
{show && <Drawer.Screen name="Article" component={Article} />}
</Drawer.Navigator>
);
}
export default function App() {
return (
<NavigationContainer>
<MyDrawer />
</NavigationContainer>
);
}

How can I access a current navigation inside a React.Component using reactnavigation 5?

I'm now using react-navigation version 5 following an expo tutorial to navigate to another screen inside a Stack (embedded in a Tab Navigator).
In the tutorial, they always used a function to init a specific screen so the navigation parameter will easy to be called inside the function's body.
Eg:
function HomeScreen({ navigation })
//Called
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
But, if I construct a React.Component instead, how can I access the navigation inside that Component to navigate to another component? plz
Please run the codes bellow on expo if my explanations are bad.
Thanks,
import * as React from 'react';
import { Button, Text, View, Alert } from 'react-native';
import { NavigationContainer } from '#react-navigation/native';
import { createStackNavigator } from '#react-navigation/stack';
import { createBottomTabNavigator } from '#react-navigation/bottom-tabs';
class Options extends React.Component {
navigaeToAnotherScreen() {
console.log('How can I access current navigation plz?');
}
render() {
return (
<View style={{ flex: 1, justifyContent: "center", alignItems: "center" }}>
<Text>Hello, world! Option</Text>
<Button title="Go To Main" onPress={() => this.navigaeToAnotherScreen() }/>
</View>
);
}
}
function OptionsScreen({ navigation }) {
return (
<Options/>
);
}
function DetailsScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Details!</Text>
<Button title="Detail" onPress={ () => navigation.push('Options')}/>
</View>
);
}
function HomeScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Home screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.navigate('Details')}
/>
</View>
);
}
function SettingsScreen({ navigation }) {
return (
<View style={{ flex: 1, justifyContent: 'center', alignItems: 'center' }}>
<Text>Settings screen</Text>
<Button
title="Go to Details"
onPress={() => navigation.push('Details')}
/>
</View>
);
}
const HomeStack = createStackNavigator();
function HomeStackScreen() {
return (
<HomeStack.Navigator>
<HomeStack.Screen name="Home" component={HomeScreen} />
<HomeStack.Screen name="Details" component={DetailsScreen} />
<HomeStack.Screen name="Options" component={OptionsScreen} />
</HomeStack.Navigator>
);
}
const SettingsStack = createStackNavigator();
function SettingsStackScreen() {
return (
<SettingsStack.Navigator>
<SettingsStack.Screen name="Settings" component={SettingsScreen} />
<SettingsStack.Screen name="Details" component={DetailsScreen} />
</SettingsStack.Navigator>
);
}
const Tab = createBottomTabNavigator();
export default function App() {
return (
<NavigationContainer>
<Tab.Navigator>
<Tab.Screen name="Home" component={HomeStackScreen} />
<Tab.Screen name="Settings" component={SettingsStackScreen} />
</Tab.Navigator>
</NavigationContainer>
);
}
try this
I noticed you didn't pass existing props to Options
function OptionsScreen({ navigation }) {
return (
<Options navigation={navigation} />
);
then try this
navigaeToAnotherScreen() {
this.props.navigation.navigate("AnyScreen");
}