React-Native DrawerNavigator Menu on both sides - javascript

I have a react native app with a DrawerNavigator. For the menu I have my own component. That works great.
Now I want to add a second side menu on the right side.
Is it possible to have two DrawerNavigator like in the Slack App?
This solution is not working for me: https://snack.expo.io/ry7lYempe
because I don't want to have a TabController as parent. Both Drawer should be accessible in all screens.
My code looks like this:
import React from 'react'
import reducer from './src/reducers'
import { DrawerNavigator } from 'react-navigation';
import SidebarMenu from './src/components/layout/SidebarMenu'
import { createStore } from 'redux';
import { Provider } from 'react-redux';
let store = createStore(reducer);
import News from './src/screens/News'
import HowTo from './src/screens/HowTo'
export default class MyApp extends React.Component {
render() {
return (
<Provider store={store}>
<MainNavigator />
</Provider>
);
}
}
const MainNavigator = DrawerNavigator(
{
News: {
path: '/news',
screen: News
},
HowTo: {
path: '/howto',
screen: HowTo
}
},
{
initialRouteName: 'News',
drawerPosition: 'left',
contentComponent: SidebarMenu
}
);
Solved after updating react-navigation to the newest version.

you can add any drawer you want, take a look at this exemple https://snack.expo.io/BJoChzewM
In your case, you may add your "MainNavigator" in another DrawerNavigator Component. don't forget to set drawerOpenRoute/drawerCloseRoute to prevent any side effects.

#KamleshKatpara Here is my solution (I nested the two navigators):
const DrawerExample = DrawerNavigator(
{
Home: {
path: '/',
screen: Home
}
},
{
initialRouteName: 'Home',
drawerPosition: 'left',
contentComponent: SidebarMenu
}
);
const MainDrawerExample = DrawerNavigator({
Drafts: {
screen: DrawerExample,
}
}, {
drawerPosition: 'right',
contentComponent: BookmarkMenu,
drawerOpenRoute: 'DrawerRightOpen',
drawerCloseRoute: 'DrawerRightClose',
drawerToggleRoute: 'DrawerRightToggle'
});

Related

Cannot nest bottomTabNavigator inside DrawerNavigator

I'm trying to nest a bottomTabNavigator inside the DrawerNavigator using the React Navigation library but an error comes up telling me to use a React component or a Navigator to for the DrawerNavigator's route.
This is the DrawerNavigator.js file where i create the DrawerNavigator.
import React, { Component } from 'react';
import {createDrawerNavigator} from 'react-navigation';
import SideBar from '../components/SideBar';
import MainTabNavigator from './MainTabNavigator';
export default createDrawerNavigator({
Home: {
screen: MainTabNavigator,
}
},{
contentComponent: SideBar
})
This is the MainTabNavigator.js file where i create the bottomTabBarNavigator
const MainTabNavigator = createBottomTabNavigator({
Home: HomeStack,
MultiBar: {
screen: () => null,
navigationOptions: ({navigation}) => ({
tabBarIcon: () => (
<CustomTabBarBottom />
)
}),
params: {
navigationDisabled: true
}
},
Video: VideoStack
}, {
tabBarComponent: props =>
<TabBarComponent
{...props}
/>,
tabBarOptions: {
showLabel: false,
},
});
export default MainTabNavigator;
Please look into this and tell me if i'm missing something, thanks in advance!
This is my code of bottomTabBar with Drawer. may this will help you.
Just add your MainTabNavigation as the first screen of your createDrawerNavigator in your code.
I have used react-navigation version 3.0
import React, { Component } from "react";
import { View, Text } from "react-native";
import {
createAppContainer,
createDrawerNavigator,
createStackNavigator
} from "react-navigation";
import Heal from "./component/tabs/Heal";
import Submit from "./component/tabs/Submit";
import { createBottomTabNavigator, BottomTabBar } from "react-navigation-tabs";
import ProfileSetting from "./component/drawerTabs/ProfileSetting";
import ChangePassword from "./component/drawerTabs/ChangePassword";
import Help from "./component/drawerTabs/Help";
import Logout from "./component/drawerTabs/Logout";
import Drawer from "./component/drawerTabs/Drawer";
import { FontTypes } from "./style/Font";
import { ColorCodes } from "./style/Color";
const TabBarComponent = props => <BottomTabBar {...props} />;
export const TabScreens = createBottomTabNavigator(
{
"Heal a case": { screen: Heal },
"Submit a case": { screen: Submit }
},
{
tabBarComponent: props => (
// <BottomTabView {...props}/>
<TabBarComponent
{...props}
activeBackgroundColor={ColorCodes.primary}
showIcon={false}
allowFontScaling={true}
activeTintColor="#fff"
inactiveTintColor="#000"
labelStyle={{ fontSize: 17, fontFamily: FontTypes.Roboto }}
tabStyle={{
justifyContent: "center",
borderWidth: 0
}}
style={
{
// backgroundColor: "red"
}
}
/>
)
}
);
export const MyDrawerNavigator = createDrawerNavigator(
{
"My Cases": {
screen: TabScreens
},
"Profile Setting": {
screen: ProfileSetting
},
"Change Password": {
screen: ChangePassword
},
Help: {
screen: Help
},
Logout: {
screen: Logout
}
},
{
contentComponent: Drawer,
drawerBackgroundColor: "white",
drawerType: "front",
contentOptions: {
labelStyle: {
fontFamily: FontTypes.Roboto,
color: ColorCodes.primary,
},
activeLabelStyle:{
color:ColorCodes.iconColor
}
}
}
);
export default createAppContainer(MyDrawerNavigator);
This is my AppNavigator.js which is used as the main app container:
import React from 'react';
import { createSwitchNavigator, createAppContainer } from 'react-navigation';
import AuthLoadingScreen from '../screens/AuthLoadingScreen';
import MainTabNavigator from './MainTabNavigator'
import AuthStackNavigator from './AuthStackNavigator';
import DrawerNavigator from './DrawerNavigator';
const MainAppNavigator = createSwitchNavigator({
AuthLoadingScreen: AuthLoadingScreen,
App: DrawerNavigator,
Auth: AuthStackNavigator,
});
const AppNavigator = createAppContainer(MainAppNavigator)
export default AppNavigator
By removing the MainTabNavigator import which i don't use at all in the file, the error goes away (which is really bizarre ).
Not sure if this still helps but I had the same problem and solved it by having all components in one file and moving the other navigators up, so that the createDrawerNavigator component is at the bottom of the file.
This looks like hoisting does not work here? I am actually confused about this, but there you go.

Adding an event handler on a createBottomTabNavigator of React Native

I have a React Native app which main navigation is accomplished using a
createBottomTabNavigator
as follows:
import React from 'react';
import { createBottomTabNavigator, createAppContainer } from 'react-navigation';
import Icon from 'react-native-vector-icons/Ionicons'
import HomeStack from './HomeStack'
import SettingsStack from './SettingsStack'
const TabNavigator = createBottomTabNavigator({
Home: {
screen: HomeStack,
navigationOptions: {
tabBarIcon:({tintColor})=>(
<Icon name="ios-home" color={tintColor} size={24}/>
)
}
},
Settings: {
screen: SettingsStack,
navigationOptions: {
tabBarIcon:({tintColor})=>(
<Icon name="ios-settings" color={tintColor} size={24}/>
)
}
}
});
export default createAppContainer(TabNavigator)
As you can see, it basically includes two other components that are stack navigators themselves. I will not include them in order to have cleaner question. What I've added to my app is real-time push notifications as described here. Everything seems to be working fine until now but I have added the notification handler:
_handleNotification = (notification) => {
this.setState({notification: notification});
};
in my HomeScreen which is part of my HomeStack (The first screen). I don't really like this structure (having the handler in my HomeScreen). I have another screen (in the same HomeStack) that I'd like to handle this new coming notification. But I assume it is not gonna happen until this other screen is not mounted. So, I was wondering, is it possible to somehow define the handler on the level of the main TabNavigator and when handled just to redirect to my dedicated screen? I assume this is a bit cleaner approach.
This is easy to implement if you just create a custom Tab Bar component.
TabBar config
import CustomTabBar from '???';
const TabRoutes = createBottomTabNavigator({
Home: {screen: HomeStack},
Settings: {screen: SettingsRoutes}
},{
tabBarComponent: CustomTabBar,
});
export default createAppContainer(TabNavigator)
CustomTabBar
import CustomTabBarItem from '???';
class CustomTabBar extends React.Component {
public constructor(props: Props) {
super(props);
this.state = {
notification: undefined
};
}
render() {
const {navigation} = this.props;
const routes = navigation.state.routes;
return (
<View>
{routes.map(route => {
// Just some basic example, create a CustomTabBarItem according your own needs
<CustomTabBarItem
key={route.key}
onPress={() => navigation.navigate(route.routeName)}
routeName={route.routeName}
/>
})}
</View>
);
}
_handleNotification = (notification) => {
this.setState({notification: notification});
};
}

How to set common color for navigation bars in all pages (react native) used createStackNavigator for navigation

How to set a common color for all navigation bar from app.js file , here we used createStackNavigator for navigations my app.js
import React, {Component} from 'react';
import { StyleSheet,} from 'react-native';
import { createStackNavigator } from 'react-navigation';
import Login from './src/pages/Login';
import SignUp from './src/pages/SignUp';
export default createStackNavigator({
Login: {
screen: Login,
navigationOptions: {
header: null
}
},
SignUp: {
screen: SignUp,
title:"SignUp",
},
});
You can use tabBarOptions at the end of your stack navigator. See this, for options available for (iOS and android) in tabBarOptions.
And for setting common color across all screens bar, use code below.
export default createStackNavigator({
Login: {
screen: Login,
navigationOptions: {
header: null
}
},
SignUp: {
screen: SignUp,
title:"SignUp",
},
},
{
tabBarOptions: {
style : {
height: 65 ,
backgroundColor: 'blue' ,
}
}
});

Render two navigators

There is a Login.js module, with this module the user can log in. If the user data is correct, then the user switches to another Secured.js module. For switching from the module to the module I use StackNavigator. In the Secured.js module, Tabs should be displayed below. For this I use TabNavigator. The problem is that when I try to render tabs, it does not work for me, because React Native says that two navigators can not be created on one page. I tried to google, but I could not find anything worthwhile, except for the advice to update React Native, saying "this is a bug of the old version" (I tried too, but it didn't help). Is there any ideas how I can fix it?
Secured.js
import React, { Component } from 'react';
import {
ScrollView,
Text,
View,
Button,
StyleSheet,
FlatList
} from 'react-native';
// Import getNews function from news.js
import { getNews } from '../screens/news';
// We'll get to this one later
import Article from '../components/Article';
import Tabs from '../screens/Tabs';
export default class Secured extends React.Component {
static navigationOptions = {
title: "Neuigkeiten",
headerTintColor: "#FF0000",
headerLeft: null,
};
constructor(props) {
super(props);
this.state = { articles: [], refreshing: true };
this.fetchNews = this.fetchNews.bind(this);
}
// Called after a component is mounted
componentDidMount() {
this.fetchNews();
}
fetchNews() {
getNews()
.then(articles => this.setState({ articles, refreshing: false }))
.catch(() => this.setState({ refreshing: false }));
}
handleRefresh() {
this.setState(
{
refreshing: true
},
() => this.fetchNews()
);
}
render() {
return (
<View>
<FlatList
data={this.state.articles}
renderItem={({ item }) => <Article article={item} />}
keyExtractor={item => item.url}
refreshing={this.state.refreshing}
onRefresh={this.handleRefresh.bind(this)}
/>
<View><Tabs /></View>
</View>
);
}
}
Tabs.js
import React, { Component } from 'react';
import { createBottomTabNavigator } from 'react-navigation';
import Secured from '../screens/Secured';
import Page1 from '../screens/Page1';
import Page2 from '../screens/Page2';
import Page3 from '../screens/Page3';
export default createBottomTabNavigator({
/// Secured: {screen:Secured,},
Page1: {screen:Page1,},
Page2: {screen:Page2,},
Page3: {screen:Page3,}
});
Firstly, it's not all happening because of react-native version is not updated. it's all about react-native navigation wrong use.
Let me explain you with two examples, one is wrong way similar with your case and second one is highly prefer, correct way to use navigators.
In React Native Navigation,
WRONG WAY
export default App extends React.Component {
render() {
/* In the root component we are rendering the app navigator */
return <AppNavigator />;
}
}
const AuthenticationNavigator = createStackNavigator({
SignIn: SignInScreen,
ForgotPassword: ForgotPasswordScreen,
});
class AuthenticationScreen extends React.Component {
render() {
return (
<AuthenticationNavigator />
);
}
}
const AppNavigator = createSwitchNavigator({
Auth: AuthenticationScreen, // This screen renders a navigator!
Home: HomeScreen,
});
In a screen inside of the navigator we are rendering another navigator You should avoid this! It will have its own navigation state and be unable To interact with any parent navigator, eg: it would not know the route "Home" exists
CORRECT & HIGHLY RECOMMENDED WAY
export default App extends React.Component {
render() {
return <AppNavigator />;
}
}
const AuthenticationNavigator = createStackNavigator({
SignIn: SignInScreen,
ForgotPassword: ForgotPasswordScreen,
});
const AppNavigator = createSwitchNavigator({
/*
* Rather than being rendered by a screen component, the
* AuthenticationNavigator is a screen component
*/
Auth: AuthenticationNavigator,
Home: HomeScreen,
});
IN YOUR CASE
import React, { Component } from 'react';
import { createBottomTabNavigator } from 'react-navigation';
import Secured from '../screens/Secured';
import Page1 from '../screens/Page1';
import Page2 from '../screens/Page2';
import Page3 from '../screens/Page3';
const Tabnav = createBottomTabNavigator({
/// Secured: {screen:Secured,},
Page1: {screen:Page1,},
Page2: {screen:Page2,},
Page3: {screen:Page3,}
});
and return the Tabnav in render function , instead of export the default. because we can't export more than one in one place.

Cannot read property 'routeName' of undefined - react navigation drawer

I keep getting this error every time i pass values to drawer config, but when i use it without passing any config it works fine.
I get error using this:
const Drawer = DrawerNavigator({
AboutUs: { screen: AboutUsScreen },
Options: { screen: OptionsScreen },
Home: { screen: HomeScreen }
}, {
initialRouteName: 'Home',
drawerPosition: 'right',
});
No error using this:
const Drawer = DrawerNavigator({
AboutUs: { screen: AboutUsScreen },
Options: { screen: OptionsScreen },
Home: { screen: HomeScreen }
});
I spent hours trying to figure it out but no luck.
Full code:
import React, { Component } from 'react';
import {
Platform,
StyleSheet,
Text,
View
} from 'react-native';
import { Card, ListItem, Button, Icon } from 'react-native-elements'
import { DrawerNavigator } from 'react-navigation'
import HomeScreen from './Home'
import OptionsScreen from './Options'
import AboutUsScreen from './AboutUs'
const Drawer = DrawerNavigator({
AboutUs: { screen: AboutUsScreen },
Options: { screen: OptionsScreen },
Home: { screen: HomeScreen }
}, {
initialRouteName: 'Home',
drawerPosition: 'right',
});
export default Drawer ;
I have added:
drawerOpenRoute: 'DrawerOpen',
drawerCloseRoute: 'DrawerClose',
drawerToggleRoute: 'DrawerToggle'
to drawer config and it's working now :)

Categories

Resources