使用动态选项卡创建TabNavigator

时间:2017-09-22 17:16:06

标签: react-native nested react-navigation tabnavigator

我相对确定我发现这是不可能的,但我想确保没有办法。

有问题的应用程序以AppNavigator StackNavigator开始。

export const AppNavigator = StackNavigator({
    Login: {
        screen: Login,
        navigationOptions: ({navigation}) => ({
            title: 'Aanmelden',
            params: {
                nuke: navigation.state.params && !!navigation.state.params.nuke,
            },
        }),
    },
    Main: {
        screen: DynamicTabBar,
        navigationOptions: ({navigation}) => ({
            title: 'Follow-up',
        }),
    },
}, {
    mode: 'modal',
    headerMode: 'none',
});

export class AppWithNavigationState extends React.Component {
    constructor(props) {
        super(props);
    }

    render() {
        return <AppNavigator navigation={addNavigationHelpers({ dispatch: this.props.dispatch, state: this.props.navigationReducer })} />
    }
}

AppWithNavigationState.propTypes = {
    dispatch: React.PropTypes.func.isRequired,
    navigationReducer: React.PropTypes.object.isRequired,
};

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

export default connect(mapStateToProps)(AppWithNavigationState);

到目前为止一切都那么好,只是DynamicTabBar不应该被渲染出来。直到用户登录(即从Login导航到Main)。

这是

的原因
const Tabs = TabNavigator({
        Start: {
            screen: UserStackNavigator,
            navigationOptions: {
                tabBarIcon: (<Icon
                    type="font-awesome"
                    name="users"
                    color="#dddddd"
                    size={20}
                />),
            },
        },
        ...Account.User.CanEnter ? {
            ConditionalTab: {
                screen: ConditionalScreen,
                navigationOptions: {
                    tabBarIcon: (<Icon
                        type="font-awesome"
                        name="recycle"
                        color="#dddddd"
                        size={20}
                    />),
                },
            }} : {},
        Settings: {
            screen: Settings,
            navigationOptions: {
                tabBarIcon: (<Icon
                    type="font-awesome"
                    name="cog"
                    color="#dddddd"
                />),
            }
        }
    },{
        ...TabNavigator.Presets.AndroidTopTabs,
        tabBarPosition: "bottom",
        tabBarOptions: {
            activeTintColor: '#eaeb65',
            showIcon: true,
            showLabel: false,
            style: { backgroundColor: '#333' },
        }
    });

export default class DynamicTabBar extends React.Component {
    constructor(props) {
        super(props);
    }
    render() {
        return <Tabs navigation={this.props.navigation} />;
    }
}
DynamicTabBar.router = Tabs.router;

...Account.User.CanEnter ? {始终为false,因为TabNavigator在用户登录并填充Account之前呈现。尝试失败,它接缝。

我想在Tabs内填充componentWillMount,但我无法设置静态路由器:DynamicTabBar.router = Tabs.router;

有关如何解决此问题的任何想法?

3 个答案:

答案 0 :(得分:4)

Yessssss! 我想我找到了办法。解决方案可能不遵循设计模式,但这是我提出的:

export default class DynamicTabBar extends React.Component {
    static router = TabRouter({
        Start: {
            screen: UserStackNavigator,
            navigationOptions: {
                tabBarIcon: (<Icon
                    type="font-awesome"
                    name="users"
                    color="#dddddd"
                    size={20}
                />),
            },
        },
        ...Account.User.CanEnter ? {
            ConditionalTab: {
                screen: ConditionalScreen,
                navigationOptions: {
                    tabBarIcon: (<Icon
                        type="font-awesome"
                        name="recycle"
                        color="#dddddd"
                        size={20}
                    />),
                },
            }} : {},
        Settings: {
            screen: Settings,
            navigationOptions: {
                tabBarIcon: (<Icon
                    type="font-awesome"
                    name="cog"
                    color="#dddddd"
                />),
            }
        }
    },{
        ...TabNavigator.Presets.AndroidTopTabs,
        tabBarPosition: "bottom",
        tabBarOptions: {
            activeTintColor: '#eaeb65',
            showIcon: true,
            showLabel: false,
            style: { backgroundColor: '#333' },
        }
    });
    constructor(props) {
        super(props);
    }

    render() {
        const tabs = TabNavigator({
            Start: {
                screen: UserStackNavigator,
                navigationOptions: {
                    tabBarIcon: (<Icon
                        type="font-awesome"
                        name="users"
                        color="#dddddd"
                        size={20}
                    />),
                },
            },
            ...Account.User.CanEnter ? {
                ConditionalTab: {
                    screen: ConditionalScreen,
                    navigationOptions: {
                        tabBarIcon: (<Icon
                            type="font-awesome"
                            name="recycle"
                            color="#dddddd"
                            size={20}
                        />),
                    },
                }} : {},
            Settings: {
                screen: Settings,
                navigationOptions: {
                    tabBarIcon: (<Icon
                        type="font-awesome"
                        name="cog"
                        color="#dddddd"
                    />),
                }
            }
        },{
            ...TabNavigator.Presets.AndroidTopTabs,
            tabBarPosition: "bottom",
            tabBarOptions: {
                activeTintColor: '#eaeb65',
                showIcon: true,
                showLabel: false,
                style: { backgroundColor: '#333' },
            }
        });

        return <Tabs navigation={this.props.navigation} />;
    }
}

路由器以静态方式分配,并在运行时动态构建。

答案 1 :(得分:0)

这是我的解决方案。我正在使用博览会。我需要标签的动态数量和内容,这些内容将从API中获得。

MainTabNavigator.js

 floatingActionButton: _createFloatingActionButton(),

BrowserScreen.js

 Widget _createFloatingActionButton() {
    if (!_tfFabVisible) {
      return null;
    }
    return FloatingActionButton(
      onPressed: _btnSubmitPressed,

答案 2 :(得分:0)

我知道这很古老,但是AFAICT在2019年仍然没有办法做到这一点。这是我想出的解决方案,我认为这很简单。

基本上,我使用自定义tabBarComponent方法指定自定义getButtonComponent,该方法要么呈现按钮,要么不基于当前用户。如果用户看不到导航项,则它将呈现一个空视图,从而具有隐藏导航项的作用。

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

class TabBar extends React.Component {
  render() {
    return (
      <BottomTabBar
        {...this.props}
        getButtonComponent={this.getButtonComponent}
      />
    )
  }

  getButtonComponent({ route }) {
    if (route.key === 'Other') {
      return () => <View /> // a view that doesn't render its children
    } else {
      return null // use the default nav button component
    }
  }
}

const AppNav = createBottomTabNavigator(
  {
    Home: HomeStack,
    Other: OtherScreen,
  },
  {
    tabBarComponent: TabBar,
  }
)