使用navigationOptions在React Navigation中根据状态更改Bottom选项卡栏

sgu*_*uha 7 react-native react-navigation

我想根据启用的功能更改屏幕上的底部选项卡.此功能列表通过登录API调用填充.

目前我有以下内容:

const TabRouteConfig = {
  Home: DashboardScreen,
  FeatureA: FeatureA,
  FeatureZ: FeatureZ,
};

const TabNavigatorConfig = {
  initialRouteName: 'Home',
  order: [
    'Home',
    'Feature A',
  ],
  tabBarPosition: 'bottom',
  lazy: true,
};

const TabNavigator1 = createBottomTabNavigator(
  TabRouteConfig,
  TabNavigatorConfig,
);

// Set the tab header title from selected route
// https://reactnavigation.org/docs/en/navigation-options-resolution.html#a-stack-contains-a-tab-navigator-and-you-want-to-set-the-title-on-the-stack-header
TabNavigator1.navigationOptions = ({ navigation }) => {
  const { index, routes } = navigation.state;
  const { routeName } = routes[index];

  return {
    headerTitle: routeName,
  };
};

const TabNavigator2 = createBottomTabNavigator(
  TabRouteConfig,
  {
   ...TabNavigatorConfig,
   order: [
      'Home',
      'Feature Z',
   ]

);

TabNavigator2.navigationOptions = TabNavigator1.navigationOptions;

const Stack = createStackNavigator({
  Main: {
    screen: props => (props.screenProps.hasFeature ?
      <TabNavigator1 /> : <TabNavigator2 />
    )
  },
})

const WrappedStack = props => (
  <View style={styles.container}>
    <Stack
      screenProps={{ hasFeature: props.hasFeature }}
    />
  </View>
);

const mapStateToProps = (state, props) => {
  return {
    ...props,
    hasFeature: state.hasFeature,
  };
};

export default connect(mapStateToProps, null)(WrappedStack);
Run Code Online (Sandbox Code Playgroud)

这主要是有效的 - 它可以在它之间动态切换TabNavigator1TabNavigator2基于它hasFeature,但它不再尊重navigationOptionsTabNavigators 的放置而且headerTitle没有设置.

有一个更好的方法吗?

vah*_*san 6

同时渲染多个导航器是一种反模式,因为这些导航器的导航状态将完全分离,您将无法从另一个导航到一个。

您可以使用tabBarComponent选项来实现您想要的。希望你能从下面的例子中得到想法:

import { createBottomTabNavigator, BottomTabBar } from 'react-navigation-tabs';

const TabNavigator = createBottomTabNavigator(
  TabRouteConfig,
  {
    tabBarComponent: ({ navigation, ...rest }) => {
      const filteredTabNavigatorRoutes = navigation.state.routes.filter(route => isRouteAllowed(route));
      return (
        <BottomTabBar
          {...rest}
          navigation={{
            ...navigation,
            state: { ...navigation.state, routes: filteredTabNavigatorRoutes },
          }}
        />
      );
    },
  },
);
Run Code Online (Sandbox Code Playgroud)

笔记:

  • 您不必react-navigation-tabs单独安装。它会随react-navigation2.0.0+自动安装。
  • isRouteAllowed是返回truefalse基于是否显示该路线的函数。确保只检查该对象中的顶级路由。
  • TabRouteConfig应该包含所有可能的选项卡,并且此逻辑仅在视觉上隐藏 TabBar 中的路由。因此,您仍然可以以编程方式导航到所有路线。因此,您可能需要在每个屏幕中添加额外的逻辑来决定是否基于hasFeature.