Deepika
Deepika

Reputation: 747

Nested stack is not accessible in react-navigation/bottom-tabs

I am currently started working in a react native project which is running in react-native: 0.67.5. In there they have used a lot of packages and some are deprecated. I have changed most of them to new package. One of the package they use is react-navigation-tabs. I have changed the coding for @react-navigation/bottom-tabs and solved most of the changes and issue. One thing I am unable to do is this bottom tabs is null for some stacks.

This is the old tabBarComponent =>

 tabBarComponent: (props: any) => {
        if (
            props.navigation.state.routes[0].routes.length > 1 &&
            props.navigation.state.routes[0].routes[1].routeName ==
                'FaciltiesStack' &&
            props.navigation.state.routes[0].routes[1].routes.length > 1 &&
            props.navigation.state.routes[0].routes[1].routes.length < 5
        ) {
            if (
                props.navigation.state.routes[0].routes[1].routes.length ==
                    4 &&
                props.navigation.state.routes[0].routes[1].routes[3]
                    .routeName == 'PaymentSuccess'
            ) {
                return <HomePageBottomTabBar {...props} />;
            }
            return null;
        }
        if (
            props.navigation.state.routes[0].routes.length > 1 &&
            props.navigation.state.routes[0].routes[1].routeName ==
                'MyProfile' &&
            props.navigation.state.routes[0].routes[1].routes[1]
        ) {
            return null;
        }
        if (
            props.navigation.state.routes[0].routes.length > 1 &&
            props.navigation.state.routes[0].routes[1].routeName ==
                'CreateOnePAAccount'
        ) {
            return null;
        }
        if (
            props.navigation.state.routes[0].routes.length > 1 &&
            props.navigation.state.routes[0].routes[1].routeName ==
                'Search' &&
            props.navigation.state.routes[0].routes[1].routes[0]
        ) {
            return null;
        }
        return <HomePageBottomTabBar {...props} />;
    },

In this, they see the nested routes of the stack and not showing the bottom-tabs for some conditions.

This is my new implementation =>

const DashboardTabNavigator = () => (
<Tab.Navigator
    tabBar={(props: any) => {
        return <HomePageBottomTabBar {...props} />;
    }}>
    <Tab.Screen
        name="ExploreStack"
        component={ExploreStack}
        options={{ headerShown: false, tabBarStyle: { display: 'none' } }}
    />
    <Tab.Screen
        name="EcardStack"
        component={EcardStack}
        options={{ headerShown: false }}
    />
    <Tab.Screen name="BookingsStack" component={BookingsStack} />
    <Tab.Screen name="CartStack" component={CartStack} />
    <Tab.Screen name="FavouritesStack" component={FavouritesStack} />
</Tab.Navigator>
);

The issue I am facing is unable to use if, else statements like the previous code. The reason is I am unable to access the nested screens of each stack. I am unable to make new implementations as the client don't want to do that and also they have more than 50 screens in each stack. It will be really hard and time consuming.

If anyone can provide me any solutions to access the screens in each stack like old package, it will be really helpful. Please le me know if there are any solutions available too.

This is the HomePageBottomTabBar.tsx =>

/* eslint-disable prettier/prettier */
import React, { Component } from 'react';
import { DeviceEventEmitter, TouchableOpacity, View } from 'react-native';
import { SvgXml } from 'react-native-svg';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';

import {
BookingsIcon,
CartIcon,
ContestIcon,
ECardIcon,
ExploreIcon,
xml,
} from '../../../navigation/bottomNav';
import { setActiveTab } from '../../../redux/actions/home';
import { Style } from '../../../../shared/styles/components/HomePage/HomePageBottomTabBar';
import { ScreenType } from '../../../../shared/constants';

import analytics from '@react-native-firebase/analytics';
import DeviceInfo from 'react-native-device-info';

interface BottomTabBarRoute {
 routeName: string;
 screen: string;
}

interface BottomTabBar {
 exploreStack: BottomTabBarRoute;
 bookingsStack: BottomTabBarRoute;
 ecardStack: BottomTabBarRoute;
 cartStack?: BottomTabBarRoute;
 favouritesStack?: BottomTabBarRoute;
}

const bottomTabBar: BottomTabBar = {
exploreStack: {
    routeName: 'ExploreStack',
    screen: 'Explore',
},
ecardStack: {
    routeName: 'EcardStack',
    screen: 'EcardStack',
},
bookingsStack: {
    routeName: 'BookingsStack',
    screen: 'MyBookings',
},
cartStack: {
    routeName: 'CartStack',
    screen: 'CartStack',
},
favouritesStack: {
    routeName: 'FavouritesStack',
    screen: 'FavouritesStack',
},
};

const bottomTabBarColor = {
 active: '#e31b23',
 inactive: '#000000',
};

interface IProps {
navigation: any;
tabData: any;
activeTabIndex: any;
setActiveTab: (tab?: any) => any;
gotoTop: () => any;
}

interface IStates {
 activeTintColor: any;
}

class HomePageBottomTabBar extends Component<IProps, IStates> {
eventListener: any;

constructor(props: IProps) {
    super(props);

    this.state = {
        activeTintColor: 0,
    };
}

componentDidMount() {
    //add listener
    this.eventListener = DeviceEventEmitter.addListener(
        'ChangeTab',
        this.handleEvent,
    );
}

handleEvent = (event: any) => {
    this.setState({ activeTintColor: event.index });
    //Do something with event object
};

componentWillUnmount() {
    //remove listener
    this.eventListener.remove();
}

_renderItem = () => {
    const { routes } = this.props.navigation.getState(); //New coding
    // const { routes } = this.props.navigation.state; // Previous coding
    return routes.map((val: any, index: any) => {
        const color =
            this.state.activeTintColor == index
                ? bottomTabBarColor.active
                : bottomTabBarColor.inactive;
        switch (val.name) {
            case bottomTabBar.exploreStack.routeName:
                return (
                    <TouchableOpacity
                        key={index}
                        onPress={async () => {
                            this._setPage(
                                bottomTabBar.exploreStack.screen,
                                index,
                            );
                            await analytics().logEvent('nav_home', {
                                unique_id: DeviceInfo.getUniqueId(),
                            });
                        }}
                        style={Style.icon}>
                        <SvgXml
                            width={Style.subIcon.width}
                            height={Style.subIcon.height}
                            xml={ExploreIcon}
                            fill={color}
                        />
                    </TouchableOpacity>
                );
            case bottomTabBar.bookingsStack.routeName:
                return (
                    <TouchableOpacity
                        disabled={false}
                        key={index}
                        onPress={async () => {
                            this._setPage(
                                bottomTabBar.bookingsStack.screen,
                                index,
                            );
                            await analytics().logEvent(
                                'nav_my_activities',
                                {
                                    unique_id: DeviceInfo.getUniqueId(),
                                },
                            );
                        }}
                        style={Style.icon}>
                        <SvgXml
                            width={Style.subIcon.width}
                            height={Style.subIcon.height}
                            xml={BookingsIcon}
                            fill={color}
                        />
                    </TouchableOpacity>
                );
            case bottomTabBar.ecardStack.routeName:
                return (
                    <TouchableOpacity
                        key={index}
                        onPress={async () => {
                            this._setPage(
                                bottomTabBar.ecardStack.screen,
                                index,
                            );
                            await analytics().logEvent('nav_ecard', {
                                unique_id: DeviceInfo.getUniqueId(),
                            });
                        }}
                        style={Style.ecard}>
                        <SvgXml
                            width={Style.ecard.w}
                            height={Style.ecard.h}
                            xml={ECardIcon}
                            fill={color}
                        />
                    </TouchableOpacity>
                );
            default:
                return null;
        }
    });
};

_setPage = (param: any, index: any) => {
    this.props.navigation.navigate(param);
    this.setState((preState) => {
        return {
            ...preState,
            activeTintColor: index,
        };
    });
    if (param == bottomTabBar.exploreStack.screen) {
        const { tabData } = this.props;
        const tabSlides =
            tabData && tabData.length ? tabData[0].fields.items : [];
        tabSlides.forEach((val: any, index: any) => {
            console.log('title - value ');
            console.log(tabSlides[index].fields.title.value);
            if (index === 0) {
                const activeTab =
                    tabSlides[index] &&
                    tabSlides[index].fields &&
                    tabSlides[index].fields.title &&
                    tabSlides[index].fields.title.value;
                const activeTabs = {
                    index,
                    activeTab,
                };

                this.props.setActiveTab(activeTabs);
            }
        });
        if (this.props.gotoTop) {
            this.props.gotoTop();
        }
    }
};

render() {
    return (
        <View style={Style.container}>
            <SvgXml
                xml={xml}
                width="100%"
                style={{
                    position: 'absolute',
                    bottom: ScreenType.iPhoneSE ? -60 : -53,
                }}
            />
            <View style={[Style.tabBarContent]}>{this._renderItem()}</View>
        </View>
    );
}
}

const mapStateToProps = (state: any) => {
    return {
     gotoTop: state.homePageReducer.homeReducer.gotoTop,
     activeTab: state.homePageReducer.homeReducer.activeTab,
     activeTabIndex: state.homePageReducer.homeReducer.activeTabIndex,
     tabData:
        state.homePageReducer.homeReducer.tabData &&
        state.homePageReducer.homeReducer.tabData.length
            ? state.homePageReducer.homeReducer.tabData
            : [],
    cardDetails: state.ecardReducer.cardReducer.data,
};
};
const mapDispatchToProps = (dispatch: any) =>
 bindActionCreators(
    {
        setActiveTab,
    },
    dispatch,
);
export default connect(
mapStateToProps,
mapDispatchToProps,)(HomePageBottomTabBar);

Upvotes: 0

Views: 25

Answers (0)

Related Questions