reactjsreact-nativereact-navigation-v5react-navigation-drawer

React Native Navigation: Check if drawer is opened or not


i have a component that is outside the Drawer tag but it's inside a NavigationContainer. So i used useRef from react to get navigate method .

So i use this example: Navigating without navigation prop

But now, i can't get the state of the drawer (is it opened or closed).

Here's my App component:

import 'react-native-gesture-handler';
import React from 'react';
import { createStore, applyMiddleware } from "redux";
import thunk from "redux-thunk";
import { Provider } from "react-redux";
import GetInformationByLocation from "./reducers/GetInformationByLocation";
import Wrapper from './components/Wrapper';
import { createDrawerNavigator } from '@react-navigation/drawer';
import { NavigationContainer } from '@react-navigation/native';
import GeoDisplay from "./components/GeoDisplay";
import { Text } from "react-native";
import { navigationRef } from "./helpers/Navigator";

const store = createStore(GetInformationByLocation, applyMiddleware(thunk));
/*
 * TODO:
 * 1. Wrap everything with parent component
 * 2. Search bar
 * 3. Save searched cities.
 * 4. Check if the city is undefined and suggest nearest city.
 * 5. Animated background
 * 6. Fancy and animated font
 * 7. Setup menu преди показване на приложението
 */

const Drawer = createDrawerNavigator();

const App = () => {
    return (
        <Provider store={store}>
            <NavigationContainer ref={navigationRef}>
                <Wrapper />
                <Drawer.Navigator initialRouteName="Home">
                    <Drawer.Screen name="Home" component={GeoDisplay} />
                </Drawer.Navigator>
            </NavigationContainer>
        </Provider >
    );
}


export default App;

and my Wrapper.js Component:

import React, { useEffect, useState } from 'react';
import { StyleSheet, View, StatusBar } from 'react-native';
import { SearchBar, Header } from 'react-native-elements';
import { MainUI } from '../styling/UI';
import * as Navigator from "../helpers/Navigator";
import { DrawerActions } from "@react-navigation/native";

const Wrapper = (props) => {

    const [search, setSearch] = useState(true);

    const openDrawer = () => {
        Navigator.navigationRef.current.dispatch(DrawerActions.openDrawer())
        setSearch(false);
    }


    useEffect(() => {
    }, []);

    return (
        <>
            <StatusBar backgroundColor={"#011E25"} />
            <Header
                leftComponent={{ icon: 'menu', color: '#fff', onPress: () => { openDrawer() } }}
                centerComponent={{ text: 'COVID Bulgaria', style: { color: '#fff' } }}
                rightComponent={{ icon: 'home', color: '#fff' }}
                backgroundColor={'#011E25'}
            />
            {search &&
                <View>
                    <SearchBar placeholder="Търси град" containerStyle={MainUI.searchContainer} />
                </View>
            }
        </>
    )

}

export default Wrapper;

I dispatch openDrawer() action with navigationRef Navigator.navigationRef.current.dispatch(DrawerActions.openDrawer()) but can't get status of the drawer.

I've tried many ways but not work.

Thanks in advance.


Solution

  • You can check if drawer is open by getting the navigation state:

    const state = navigationRef.current.getRootState();
    const isDrawerOpen = state.history.some((it) => it.type === 'drawer');
    

    The above code assumes that drawer is at root. If it's nested, you'll need to traverse the state to find the state object with type: 'drawer'.

    It's not clear why you need to check it from the question. Normally you shouldn't need to check it. If you dispatch DrawerActions.openDrawer() if drawer is already open, nothing will happen. So the check is unnecessary. If you want to close the drawer if it was open, you can dispatch DrawerActions.toggleDrawer() instead.