how to hide Drawer on sidebar menu click React native - react-native

hi i want to close drawer on sidebar menu click...
"Drawer code below which in index.js file"
`<Drawer ref={(ref) => { this._drawer = ref; }}
content={}
onClose={() => this.closeDrawer()}`
"and here is sidebar code sidebar.js"

If you define ref on drawer as follows:
<Drawer ref="drawer"
you can close it using:
this.refs.drawer.close();
or as you defined:
<Drawer ref={(ref) => { this._drawer = ref; }}
you can close it using:
this._drawer.close();
Call it inside your closeDrawer().

Simple solution for latest versions: Add drawerLockMode property
const AppNavigator = createDrawerNavigator(
{
Home: { screen: HomeScreen },
List: { screen: ListScreen }
},
{
initialRouteName: "Home",
headerMode: "none",
drawerLockMode:'locked-closed'
});

Related

Navigation drawer is not opening and toggleDrawer not found

Trying to create drawer using React-Navigation.
Using React Native 0.59, Installed React-Navigation 3.x, has done linking react-native link react-native-gesture-handler.
Create routes using React-Navigation, called Route.js:
const Drawer = createDrawerNavigator(
{
Settings: {
screen: HomeScene,
navigationOptions: {
title: 'Home',
drawerIcon: () => (
<Icon name="home" style={{ color: colors.white, fontSize: 24 }} type="Ionicons" />
)
}
}
},
{
contentComponent: props => <GlobalSideMenu {...props} />
}
);
const AppNavigator = createStackNavigator(
{
Home: {
screen: HomeScene,
navigationOptions: {
header: null
}
},
Drawer: {
screen: Drawer,
navigationOptions: {
header: null
}
}
},
{
initialRouteName: 'Home'
}
);
export default createAppContainer(AppNavigator);
Then in the header, drawer icon:
<Button icon transparent onPress={() => this.props.navigation.toggleDrawer()}>
<Icon name={icon('menu')} type="Ionicons" style={styles.menuColor} />
</Button>
It gives me error : toggleDrawer() is undefined.
Then I change it to :
this.props.navigation.dispatch(DrawerActions.toggleDrawer());
Now, there is no error, but the drawer is not opening.
This is usually the case if you are attempting to open the drawer from outside the drawer navigator's set of screens.
this.props.navigation.toggleDrawer is only defined if you are in Settings, which I guess is not the case.
You can either rearrange the navigation so that the drawer is present on the screen you are calling toggleDrawer from, or you can navigate to Settings first.
<Button
icon
transparent
onPress={() => {
this.props.navigation.navigate('Settings');
this.props.navigation.dispatch(DrawerActions.openDrawer());
}}
>
<Icon name={icon('menu')} type="Ionicons" style={styles.menuColor} />
</Button>
Here is an example to clarify.

react navigation - DrawerNavigator for Header Menu icon inside TabNavigator-> StackNavigator

I want to display HeaderLeft Menu icon globally in all screens. When I click on Menu Icon, I need to display Drawer Menu. I use "OpenDrawer", "CloseDrawer" methods for open/close drawer menu.
But I am always getting "undefined is not a function (evaluating 'props.navigation.openDrawer()')". I also tried the following
props.navigation.dispatch(DrawerActions.openDrawer())
props.navigation.navigate(openDrawer())
But None of the above worked. Here is my partial code
const MenuButton = (props) => {
return (
<View>
<TouchableOpacity onPress={() => { props.navigation.dispatch(DrawerActions.openDrawer())} }>
<Text>Menu</Text>
</TouchableOpacity>
</View>
)
};
const MyDrawerNavigator = createDrawerNavigator(
{
Wishist: {
screen: wishlist
},
},
{
contentComponent: SideMenuScreen,
drawerWidth: 200,
}
);
const AppNavigator = createBottomTabNavigator({
Home: {
screen: createStackNavigator({
Home: {
screen: Home
},
Contact: {
screen: Contact
}
},
{
defaultNavigationOptions: ({ navigation }) => ({
headerStyle: {
backgroundColor: 'white',
borderWidth:0,
borderBottomWidth:0
},
headerTitle: headerTitleNavigationOptions('HOME'),
headerLeft: <MenuButton navigation={navigation}/>,
headerRight: headerRightNavigatorOptions(navigation)
})
}),
navigationOptions: ({ navigation }) => ({
headerStyle: {
backgroundColor: 'white',
borderWidth:0,
borderBottomWidth:0
},
}),
}},
{
tabBarOptions: {
showLabel: false,
style: {
backgroundColor: 'white',
borderTopWidth:1
}
},
initialRouteName: 'Home',
tabBarComponent: TabBarBottom,
tabBarPosition: 'bottom',
animationEnabled: false,
swipeEnabled: false
}
);
const App = createAppContainer(AppNavigator);
you need to import the DrawerActions in your component from react-navigation-drawer as explained in the docs
DrawerActions is an object containing methods for generating actions specific to drawer-based navigators. Its methods expand upon the actions available in NavigationActions.
The following actions are supported:
openDrawer - open the drawer
closeDrawer - close the drawer
toggleDrawer - toggle the state, ie. switche from closed to open and
vice versa
import { DrawerActions } from 'react-navigation-drawer';
this.props.navigation.dispatch(DrawerActions.openDrawer())
The react-navigation api do not provide more information, but you can consult the NavigationActions api reference for more information.
NavigationActions reference
All NavigationActions return an object that can be sent to the router using navigation.dispatch() method.
Note that if you want to dispatch react-navigation actions you should use the action creators provided in this library.
You need to import NavigationActions in your component and then you can dispatch your action with something like this.props.navigation.dispatch(navigateAction);
import { NavigationActions } from 'react-navigation';
const navigateAction = NavigationActions.navigate({
routeName: 'Profile',
params: {},
action: NavigationActions.navigate({ routeName: 'SubProfileRoute' }),
});
this.props.navigation.dispatch(navigateAction);
also as explained from Ashwin Mothilal, make sure you are passing the navigation prop inside your component. For example you can run a console.warn(props) and immediatly see the result on the emulator.
This is your component:
import { DrawerActions } from 'react-navigation-drawer';
const MenuButton = (props) => {
return (
<View>
<TouchableOpacity onPress={() => {
console.warn(props);
props.navigation.dispatch(DrawerActions.openDrawer());
}}>
<Text>Menu</Text>
</TouchableOpacity>
</View>
)
};
At first, just console the props in Menu button and check if you get openDrawer or closeDrawer or any other method you are looking for then you can call it.

React native set state from drawer navigator to other component

On first screen I have a component having some listing of products say ProductListing.js. And on drawer navigator I have some check boxes. I want to set state of ProductListing.js when I am clicking on any check box of navigator.
App.js
import React, {Component} from 'react';
import Router from './src/config/routes';
export default class App extends React.Component {
render () {
return (
<Router/>
);
}
}
Router.js
export default DrawerNavigator({
Dashboard: {screen: Dashboard},
CreateLogin: {screen: CreateLogin},
Test: {screen: Test}
}, {
contentComponent: SideMenu,
drawerWidth: 300,
drawerPosition: 'right'
});
SideMenu.js
render () {
const { data, searchTerm, searchAttribute, ignoreCase, checked } = this.state;
return (
<View style={styles.container}>
<ScrollView>
<View>
<TextInput
style={styles.search} placeholder={"Search"}
onChangeText={searchTerm => this.setState({ searchTerm })} />
<SearchableFlatList
data={data} searchTerm={searchTerm}
searchAttribute={searchAttribute} ignoreCase={ignoreCase}
renderItem={({ item, index }) => <CheckBox
title={item.name +' ('+ item.count+')'}
onPress={() => this.handleChange(item.id)}
checked={checked[item.id]} />
}
keyExtractor={({id}, index) => index.toString()} />
</View>
</ScrollView>
<View style={styles.footerContainer}>
<Text>Apply filter by choosing filter values</Text>
</View>
</View>
);
}
}
ProductListing.js
constructor(props){
super(props);
this.state ={ isLoading: true,isloadmore: false, page :1,dataSource: [],countryFilter:0, gradesFilter:'',country:'',totalRecord:0};
}
render(){
const { navigation } = this.props;
return(
<View style={{flexDirection:'column',paddingRight:8}}>
<Button
title='Filter'
buttonStyle={{backgroundColor:'#000000',borderRadius:2}}
onPress={() => navigation.dispatch(DrawerActions.openDrawer())}
/>
</View>
);
}
Now on click of handleChange in SideMenu.js I want to update state of gradesFilter in ProductListing.js where I am updating my product listing.
You can easily achieve this with a portal! Take a look here.
You can pass the parameters from drawer to the Product screen via navigation params.
For this, you need to stackNavigator inside your DrawerNavigator like:
Router:
const MyStack = StackNavigator({
Dashboard: {screen: Dashboard},
CreateLogin: {screen: CreateLogin},
Test: {screen: Test}
});
const MyDrawer = DrawerNavigator({
Main: { screen: MyStack }
},
{
contentComponent: SideMenu,
drawerWidth: 300,
drawerPosition: 'right'
});
export const Router = StackNavigator({
Login: {screen: Login},
Drawer: {
screen: MyDrawer,
navigationOptions: { header: null } } //prevent double header
});
Now you can navigate and pass parameter from login or Dashboard or anyother screen via Drawer like
_login() {
this.props.navigation.navigate('Drawer', { parameter: userName });
}
And to use this parameter you need to access:
const { parameter } = this.props.navigation.state.params;
which you can further use to set state like
this.setState({
productSelection: parameter)};
Another approach can be via, listener/ Callback handler.

How to change screen using stackNavigation in React Native?

I have one screen which in header consists button to go to another screen.
I have already model here, but it doesn't work: As shown below I want to change the screen from RecipeList to NewRecipeForm using Button in header
const AppStackNavigator = createStackNavigator({
List: {
screen: RecipesList,
navigationOptions: {
title:'RecipesList',
headerLeft: (
<Button onPress={()=>this.props.navigation.navigate('NewRecipeForm')}>
<Text>+</Text>
</Button>
)
}},
NewRecipeForm: {screen: CreateRecipeForm,
navigationOptions: {title:'Add new recipe'}},
Details: {screen: RecipesDetails, navigationOptions: {title:'RecipeDetails'}},
export default class App extends React.Component {
render() {
return <AppStackNavigator initialRouteName='List' />;
}
}
I hope that you will help me with solution
You may use your stack navigator as like below, you can able to destructure your navigation property while giving your navigationOptions property as well in the createStackNavigator itself
const AppStackNavigator = createStackNavigator({
List: {
screen: RecipesList,
navigationOptions: ({navigation}) => { //destructure the navigation property here
return {
title: 'RecipesList',
headerLeft: (
<Button onPress={() => navigation.navigate('NewRecipeForm')}>
<Text>+</Text>
</Button>
)
}
}
},
NewRecipeForm: {
screen: CreateRecipeForm,
navigationOptions: { title: 'Add new recipe' }
},
Details: { screen: RecipesDetails, navigationOptions: { title: 'RecipeDetails' } }
});
You cannot access the props of your component in headerLeft, but you can directly use the navigation like this :
<Button onPress={()=> navigation.navigate('NewRecipeForm')}>
You can use following code inside your RecipesList Component instead of having it inside createStackNavigator(). See this Snack for full implementation.
static navigationOptions = ({ navigation }) => {
return {
headerTitle: "RecipesList",
headerLeft: (
<Button
onPress={() => navigation.navigate('NewRecipeForm')}
title="+"
/>
),
};
};

Add hamburger button to React Native Navigation

I'm very new to React-Native so I definitely may be missing something. But all I want to do is add a hamburger type button to a settings page in the main Navigation bar. I have set up a link in the main part of that works the way I want hamburger button to work.
Screenshot
import React from 'react';
import { AppRegistry, Text, View, Button } from 'react-native';
import { StackNavigator } from 'react-navigation';
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
headerLeft: <Button onPress={ WHAT GOES HERE?? } title= "=" />
};
render() {
const { navigate } = this.props.navigation;
return (
<Button
onPress={() => navigate('Settings')}
title="Link to Settings" />
);
}
}
class Settings extends React.Component {
static navigationOptions = {
title: 'Settings',
headerLeft: <Button title= "=" />
};
render() {
return <Text>Hello, Settings!</Text>;
}
}
const SimpleApp = StackNavigator({
Home: { screen: HomeScreen },
Settings: { screen: Settings}
});
AppRegistry.registerComponent('NavPractice', () => SimpleApp);
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
Having this, you're very close to the solution.
static navigationOptions = {
title: 'Welcome',
headerLeft: <Button onPress={ WHAT GOES HERE?? } title= "=" />
};
A little-known fact is that navigationOptions accepts a function that returns navigation options. That function accepts some props, navigation one of them. Know this, adjust your code a little.
static navigationOptions = function(props) {
return {
title: 'Welcome',
headerLeft: <Button onPress={() => props.navigation.navigate('DrawerOpen')} title= "=" />
}
};
check this link with same issue https://github.com/react-community/react-navigation/issues/1539
check navigationOptions
navigationOptions: ({ navigation }) => ({
title: 'Schedules', // Title to appear in status bar
headerLeft: <Icon name="menu" size={35}
onPress={ () => navigation.navigate('DrawerOpen') } />
from
const SchedulesStack = StackNavigator({
Schedules: {
screen: SchedulesScreen,
navigationOptions: ({ navigation }) => ({
title: 'Schedules', // Title to appear in status bar
headerLeft: <Icon name="menu" size={35} onPress={ () => navigation.navigate('DrawerOpen') } />
})
}
});
const Homestack = StackNavigator({
Home: {
Screen: Home
navigationOptions: ({ navigation }) => ({
title: 'Home', // Title to appear in status bar
headerLeft: <Icon name="menu" size={35} onPress={ () => navigation.navigate('DrawerOpen') } />
})
}
});
const Root = DrawerNavigator({
Home: {
screen: HomeStack,
navigationOptions: {
title: 'Home' // Text shown in left menu
}
},
Schedules: {
screen: SchedulesStack,
navigationOptions: {
title: 'Schedules', // Text shown in left menu
}
}
}
})
In the above code it seems you are adding options to the sidebar and navigating to the sidebar menus.
//sidebar menu no.1
class HomeScreen extends React.Component {
static navigationOptions = {
title: 'Welcome',
headerLeft: <Button onPress={//action taken when option in the menu bar is clicked} title= "//the title of the screen where you will navigate and the sidebar menu lable" />
};
render() {
const { navigate } = this.props.navigation;
return (
<Button
onPress={() => navigate('Settings')}
title="Link to Settings" />
);
}
}
In this way you can create as many drawer options as you can.. now how to combine drawer options:
//react navigation provides you with DrawerNavigator API
const MyApp = DrawerNavigator({
Home: {
screenA: HomeScreen ,
},
Settings: {
screen: MySettingScreens,
},
});
The drawer also comes with a prop that is screenProps={/* this prop will get passed to the screen components and nav options as props.screenProps */}, like this :
<MyApp
screenProps={/* this prop will get passed to the screen components and nav options as props.screenProps */}
/>
Following are the props that react navigator provide to open/close drawer.
this.props.navigation.navigate('DrawerOpen'); // open drawer
this.props.navigation.navigate('DrawerClose'); // close drawer
You can also set the drawer style according to you, like this:
drawerWidth - Width of the drawer
drawerPosition - Options are left or right. Default is left position.
contentComponent - By default there is no scrollview available in the drawer. In order to add scrollview in the drawer you need to add contentComponent in the configuration.
contentOptions - As the name suggest these are used to give color to the active and inactive drawer items (label).
Cheers :)