如何在反应导航中检测何时打开抽屉?

dan*_*doe 6 react-native react-navigation

我在我的应用程序中使用react-navigation的DrawerNavigator。我想检测用户何时拖动打开侧边菜单,以便我可以执行某些操作,例如关闭打开的键盘。我怎样才能做到这一点?我似乎无法在文档中找到解决方案。谢谢。

这是我的代码

import React from 'react';
import { Dimensions } from 'react-native';
import { Icon } from 'react-native-elements';
import { DrawerNavigator, StackNavigator, addNavigationHelpers } from 'react-navigation';


//redux related imports
import { createStore, combineReducers } from 'redux';
import { Provider, connect } from 'react-redux';

import Attendance from './containers/pages/Attendance';
import Fees from './containers/pages/Fees';
import Exams from './containers/pages/Exams';
import InitializeUser from './containers/pages/InitializeUser';
import Landing from './Landing';
import Login from './containers/pages/Login';
import Search from './containers/pages/Search';
import Staff from './containers/pages/Staff';
import Stats from './containers/pages/Stats';
import Students from './containers/pages/Students';
import Verification from './containers/pages/verify';
import ProfileDetail from './components/pages/ProfileDetail';
import FeesDetail from './containers/pages/FeesDetails';


import MainReport from './containers/pages/Reports/Main_Report';
import AcademicDetails from './containers/pages/Reports/Student_Academic_Details';
import { Constants } from './config';
import ResultsLanding from './containers/pages/Reports/ResultsLanding';
import { CustomDrawerContentComponent } from '../src/components/base/SideMenu';


const screenWidth = Dimensions.get('window').width;
const MainPages = DrawerNavigator({
  StudentsPage: {
    path: '/Students',
    screen: Students
  },
  SearchPage: {
    path: '/Seacrh',
    screen: Search
  },

  Staff: {
    path: '/Staff',
    screen: Staff
  },

  Fees: {
    path: '/Fees',
    screen: Fees
  },
  Stats: {
    path: '/Stats',
    screen: Stats
  },
  Results: {
    screen: ResultsLanding,
    navigationOptions: {
      tintColor: 'red',
      flex: 1,
      drawerIcon: ({ tintColor }) => (
        <Icon
          name="content-paste"
          color={tintColor}
        />
      )
    }
  },
  Attendance:
  {
    path: '/Attendance',
    screen: Attendance
  },
},
  {
    initialRouteName: 'StudentsPage',
    contentOptions: {
      activeTintColor: Constants.ui.THEME,
      activeBackgroundColor: 'rgba(0,0,0,0.1)',
      inactiveTintColor: 'rgba(0,0,0,0.6)',
      labelStyle: {
        fontSize: 12,
        marginLeft: 10,
      },
    },

    drawerWidth: screenWidth > 320 ? 300 : 250,
    contentComponent: CustomDrawerContentComponent

  });

export const Navigator = StackNavigator({
  LandingPage: {
    screen: Landing,
    navigationOptions: {
      header: null
    }
  },
  LoginPage: {
    screen: Login,
    navigationOptions: {
      header: null
    },
  },
  ProfileDetailPage: {
    screen: ProfileDetail,
    headerMode: 'screen',
    navigationOptions: {
      header: null
    }
  },
  FeesDetailPage:
  {
    screen: FeesDetail,
    navigationOptions: {
      header: null
    },
  },
  VerifyPage: {
    screen: Verification,
    navigationOptions: {
      header: null
    },
  },
  InitUserPage: {
    screen: InitializeUser,
    navigationOptions: {
      header: null
    },
  },
  MainPages: {
    screen: MainPages,
    navigationOptions: {
      header: null
    }
  },

  MainReportPage: {
    screen: MainReport,
    navigationOptions: {
      header: null
    }
  },
  ExamsMainPage: {
    screen: Exams,
    navigationOptions: {
      header: null
    }
  },
  AcademicDetailsPage: {
    screen: AcademicDetails,
    navigationOptions: {
      header: null
    }
  },

});  

const initialState = MainPages.router.getStateForAction(
  MainPages.router.getActionForPathAndParams('StudentsPage'));  

const navReducer = (state = initialState, action) => {
  const nextState = MainPages.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 (
      <MainPages 
        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>
    );
  }
}
Run Code Online (Sandbox Code Playgroud)

此处输入图像描述这是运行代码时出现的错误的屏幕截图

wen*_*ris 5

简单地说,如果您使用 react-navigation v5 -

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

const isOpen: boolean = useIsDrawerOpen()
Run Code Online (Sandbox Code Playgroud)

那么你必须通过钩子useEffect订阅“isOpen”标志:

useEffect(() => {
    if (!isOpen) {
      // Your dismiss logic here 
    }
}, [isOpen])
Run Code Online (Sandbox Code Playgroud)

您的自定义 Drawer 可以看起来像DrawerContent

希望有帮助

  • 该钩子现在称为“useDrawerStatus”,其值是一个字符串(“open”或“close”),请参阅[这部分](https://reactnavigation.org/docs/upgrading-from-5文档的 .x/#drawer-status-is-now-a-string-instead-of-a-boolean) (3认同)

Pat*_*ham 2

通过遵循Redux 集成指南并将其修改为使用 DrawerNavigator 而不是 StackNavigator,我能够检测到 DrawerNavigator 的打开和关闭侧面菜单操作。这是我的index.ios.js文件中的内容。App靠近我使用的类的底部componentWillReceiveProps,每次抽屉打开或关闭时都会显示警告。

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);
Run Code Online (Sandbox Code Playgroud)

当我打开抽屉并展开时,警告nextProps如下所示:

在此输入图像描述

然后在我关闭抽屉后,新的警告出现如下:

在此输入图像描述

nextProps.nav是一个有两个键的对象,routes并且index. 当抽屉打开时,index变为1,当抽屉关闭时,索引变为0

使用该信息,您可以添加 if 语句以在抽屉打开时执行必要的操作。