在 React Navigation 5 中从按钮打开两个抽屉之一
Open one of two drawers from button in react navigation 5
在 React Navigation v5 之前,以前可以使用 getCustomActionCreators
从按钮打开特定的抽屉。
这里有一个这样做的例子:
不过,这个功能好像已经被移除了。有没有办法在 React Navigation 5 中做到这一点?
这可以通过创建自定义路由器来实现。
以下是一些重要的见解:
- 导航器冒出他们不处理的操作。这意味着我们需要为每个抽屉创建自定义操作。
- 为了创建自定义操作,我们需要创建自定义路由器。
- 为了使用自定义路由器,我们需要构建一个新的导航器。
这些注释已针对以下版本进行了验证:
- @react-navigation/native: 5.8.0
- @react-navigation/drawer: 5.10.0
- @react-navigation/routers: 5.5.0
自定义操作:
export const openSecondDrawerAction = { type: 'OPEN_SECOND_DRAWER' };
调度自定义操作的辅助函数(可选)
export const openSecondDrawer = navigation => {
navigation.dispatch(openSecondDrawerAction);
};
自定义路由器
import { DrawerRouter } '@react-navigation/routers';
const SecondDrawerRouter = options => {
const router = DrawerRouter(options);
return {
...router,
getStateForAction: (state, action, options) => {
switch (action.type) {
case 'OPEN_SECOND_DRAWER':
// CATCH THIS ACTION BUT MODIFY TO AN OPEN_DRAWER
return router.getStateForAction(state, {
...action,
type: 'OPEN_DRAWER'
}, options);
case 'OPEN_DRAWER':
// DO NOT HANDLE THIS ACTION, LET IT BUBBLE TO THE PRIMARY DRAWER
return null;
default:
return router.getStateForAction(state, action, options);
}
}
};
};
自定义导航器
这基于 createDrawerNavigator 中的代码。
import { useNavigationBuilder, createNavigatorFactory } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { DrawerView, DrawerActions } from '@react-navigation/drawer';
const createDrawerNavigatorWithRouter = router => {
function DrawerNavigator({ initialRouteName, openByDefault, backBehavior, children, screenOptions, ...rest }) {
const { state, descriptors, navigation } = useNavigationBuilder(router, {
initialRouteName,
openByDefault,
backBehavior,
children,
screenOptions
});
return <DrawerView {...rest} state={state} descriptors={descriptors} navigation={navigation} />;
}
return createNavigatorFactory(DrawerNavigator)();
};
创建导航器实例
现在我们可以控制两个抽屉,其中第一个作为标准抽屉处理,第二个使用修改后的路由器:
const FirstDrawer = createDrawerNavigator()
const SecondDrawer = createDrawerNavigatorWithRouter(SecondDrawerRouter)
嵌套导航器
需要嵌套导航器如下:
<FirstDrawer.Navigator>
// then wrap the required FirstDrawer.Screen entry/ies with:
<SecondDrawer.Navigator>
</SecondDrawer.Navigator>
</FirstDrawer.Navigator>
这是一个概念视图,不幸的是,定义嵌套导航器并不像这样简单 - 您需要定义屏幕组件,这些组件本身包含在第二个导航器中
重复
应该可以为第三个或更多抽屉复制上述内容(使用不同的操作名称)。 createDrawerNavigatorWithRouter
可以重复使用而无需重复,因为它对抽屉导航器是通用的。
在 React Navigation v5 之前,以前可以使用 getCustomActionCreators
从按钮打开特定的抽屉。
这里有一个这样做的例子:
不过,这个功能好像已经被移除了。有没有办法在 React Navigation 5 中做到这一点?
这可以通过创建自定义路由器来实现。
以下是一些重要的见解:
- 导航器冒出他们不处理的操作。这意味着我们需要为每个抽屉创建自定义操作。
- 为了创建自定义操作,我们需要创建自定义路由器。
- 为了使用自定义路由器,我们需要构建一个新的导航器。
这些注释已针对以下版本进行了验证:
- @react-navigation/native: 5.8.0
- @react-navigation/drawer: 5.10.0
- @react-navigation/routers: 5.5.0
自定义操作:
export const openSecondDrawerAction = { type: 'OPEN_SECOND_DRAWER' };
调度自定义操作的辅助函数(可选)
export const openSecondDrawer = navigation => {
navigation.dispatch(openSecondDrawerAction);
};
自定义路由器
import { DrawerRouter } '@react-navigation/routers';
const SecondDrawerRouter = options => {
const router = DrawerRouter(options);
return {
...router,
getStateForAction: (state, action, options) => {
switch (action.type) {
case 'OPEN_SECOND_DRAWER':
// CATCH THIS ACTION BUT MODIFY TO AN OPEN_DRAWER
return router.getStateForAction(state, {
...action,
type: 'OPEN_DRAWER'
}, options);
case 'OPEN_DRAWER':
// DO NOT HANDLE THIS ACTION, LET IT BUBBLE TO THE PRIMARY DRAWER
return null;
default:
return router.getStateForAction(state, action, options);
}
}
};
};
自定义导航器
这基于 createDrawerNavigator 中的代码。
import { useNavigationBuilder, createNavigatorFactory } from '@react-navigation/native';
import { createStackNavigator } from '@react-navigation/stack';
import { DrawerView, DrawerActions } from '@react-navigation/drawer';
const createDrawerNavigatorWithRouter = router => {
function DrawerNavigator({ initialRouteName, openByDefault, backBehavior, children, screenOptions, ...rest }) {
const { state, descriptors, navigation } = useNavigationBuilder(router, {
initialRouteName,
openByDefault,
backBehavior,
children,
screenOptions
});
return <DrawerView {...rest} state={state} descriptors={descriptors} navigation={navigation} />;
}
return createNavigatorFactory(DrawerNavigator)();
};
创建导航器实例 现在我们可以控制两个抽屉,其中第一个作为标准抽屉处理,第二个使用修改后的路由器:
const FirstDrawer = createDrawerNavigator()
const SecondDrawer = createDrawerNavigatorWithRouter(SecondDrawerRouter)
嵌套导航器 需要嵌套导航器如下:
<FirstDrawer.Navigator>
// then wrap the required FirstDrawer.Screen entry/ies with:
<SecondDrawer.Navigator>
</SecondDrawer.Navigator>
</FirstDrawer.Navigator>
这是一个概念视图,不幸的是,定义嵌套导航器并不像这样简单 - 您需要定义屏幕组件,这些组件本身包含在第二个导航器中
重复
应该可以为第三个或更多抽屉复制上述内容(使用不同的操作名称)。 createDrawerNavigatorWithRouter
可以重复使用而无需重复,因为它对抽屉导航器是通用的。