How to detect when the drawer is opened in react-navigation?

I was able to detect the DrawerNavigator's open and close side menu actions by following the Redux Integration guide and modifying it to use a DrawerNavigator instead of StackNavigator. Here is what I have inside my index.ios.js file. Near the bottom within the App class I use componentWillReceiveProps which displays a warning every time the drawer opens or closes.

import React from 'react';
import {
  AppRegistry,
  Image,
  Text,
  View,
  ScrollView
} from 'react-native';
import {DrawerNavigator, DrawerItems, addNavigationHelpers } from 'react-navigation';
import { Provider, connect } from 'react-redux'
import { createStore, combineReducers } from 'redux'

class MyHomeScreen extends React.Component {
  static navigationOptions = {
    drawerLabel: 'Home',
    drawerIcon: ({ tintColor }) => (
      <Image
        source={require('./images/Groups.png')}
        style={{tintColor: tintColor, width: 26, height: 26}}/>
    ),
  };
  render() {
    return (
      <View>
        <Text>Home Screen</Text>
      </View>
    );
  }
}

class MyNotificationsScreen extends React.Component {
  static navigationOptions = {
    drawerLabel: 'Notifications',
    drawerIcon: ({ tintColor }) => (
      <Image
        source={require('./images/Events.png')}
        style={{tintColor: tintColor, width: 26, height: 26}}/>
    ),
  };
  render() {
    return (
      <View>
        <Text>Notifications Screen</Text>
      </View>
    );
  }
}

const NavDemo = DrawerNavigator({
  Home: { screen: MyHomeScreen },
  Notifications: { screen: MyNotificationsScreen }
}, {
  tabBarOptions: {
    activeTintColor: '#e91e63',
  },
  drawerWidth: 200,
  drawerPosition: 'left',
  contentComponent: props => <ScrollView><DrawerItems {...props} /></ScrollView>
});

const initialState = NavDemo.router.getStateForAction(NavDemo.router.getActionForPathAndParams('Home'));

const navReducer = (state = initialState, action) => {
  const nextState = NavDemo.router.getStateForAction(action, state);
  return nextState || state;
};

const appReducer = combineReducers({
  nav: navReducer
});

class App extends React.Component {
  componentWillReceiveProps(nextProps) {
    console.warn('nextProps: ' + JSON.stringify(nextProps, null, 4))
  }
  render() {
    return (
      <NavDemo navigation={addNavigationHelpers({
        dispatch: this.props.dispatch,
        state: this.props.nav,
      })} />
    );
  }
}

const mapStateToProps = (state) => ({
  nav: state.nav
});

const AppWithNavigationState = connect(mapStateToProps)(App);

const store = createStore(appReducer);

class Root extends React.Component {
  render() {
    return (
      <Provider store={store}>
        <AppWithNavigationState />
      </Provider>
    );
  }
}

AppRegistry.registerComponent('NavDemo', () => Root);

When I open the drawer and expand the warning nextProps looks like this:

enter image description here

And then after I close the drawer, the new warning appears like this:

enter image description here

nextProps.nav is an object with two keys, routes and index. When the drawer opens, index becomes 1, and when it closes, index becomes 0.

Using that information, you can add an if statement to perform your necessary actions when the drawer opens.


Simply, if you use react-navigation v5 -

import { useIsDrawerOpen } from '@react-navigation/drawer'

const isOpen: boolean = useIsDrawerOpen()

then you have to subscribe on "isOpen" flag by hook useEffect:

useEffect(() => {
    if (!isOpen) {
      // Your dismiss logic here 
    }
}, [isOpen])

Your custom Drawer can look like DrawerContent

Hope it helped