2

I am beginner in React Native. I am getting stuck in one issue. I have one Parent component Home.js in which there is Tab navigator on click of tab 3 child components replace based on selected key. In same page, I have custom drawer.Now, I want to change tabs on click of custom drawer's option & same thing when my 1st tab selected 1st option of drawer also set selected. How can i achieve this.

Here is my navigation Drawer :

export default MyDrawerNavigator = DrawerNavigator({
    Page1: {
        screen: props => <Home {...props} />,
    }
},
    {
        contentComponent: props => (<CustomSideMenu {...props} />),
        drawerWidth: (getScreenWidth() * 2.5) / 3,
    }
);

Here is my Home class I want to access goToNextTab() inside Custom drawer

export class Home extends React.Component {

    static navigationOptions = hidenavigation;

    constructor(props) {
        super(props);
    }

    apply_header = (val) => {
        this.props.navigation.setParams({ Title: val });
    }

    goToNextTab = (tabName) => {
        this.setState({ activeTab: tabName });
    }

    openDrawer() {
        this.props.navigation.openDrawer();
    }

    tabs = [{
        key: 'Dashboard',
        icon: 'speedometer',
        label: 'Dashboard',
        pressColor: 'rgba(255, 255, 255, 0.16)'
    },
    {
        key: 'Add Diamond',
        icon: 'plus-circle-outline',
        label: 'Add Diamond',
        pressColor: 'rgba(255, 255, 255, 0.16)'
    },
    {
        key: 'Diamond',
        icon: 'diamond-stone',
        label: 'Diamond',
        pressColor: 'rgba(255, 255, 255, 0.16)'
    }]

    state = {
        activeTab: 'Dashboard',
        showFooter: true
    };

    renderIcon = icon => ({ isActive }) => (
        <Icon size={24} color={isActive ? COLOR.action_bar : COLOR.tab_deselected_text_color} name={icon} />
    )

    renderTab = ({ tab, isActive }) => (
        <FullTab isActive={isActive} key={tab.key} label={tab.label} labelStyle={isActive ? style.activeText : style.deactiveText} renderIcon={this.renderIcon(tab.icon)} />
    )

    render() {
        const propsForChild = {
            goToNextTab: (tabName) => this.goToNextTab(tabName),
            openDrawer: () => this.openDrawer()
        };

        const propsForNav = {
            nav: this.props,
            openDrawer: () => this.openDrawer()
        };

        const addDimPropsForChild = {
            openDrawer: () => this.openDrawer()
        }
        return (
            <View style={{ flex: 1 }}>
                <View style={{ flex: 1 }}>
                    {
                        this.state.activeTab === 'Add Diamond' ? <Add_Dimond_Stack screenProps={addDimPropsForChild} /> : this.state.activeTab === 'Diamond' ? <Dimond_List_stack screenProps={propsForNav} /> : <Dashboard_Stack screenProps={propsForChild} />
                    }
                </View>
                {
                    this.state.showFooter ?
                        <BottomNavigation activeTab={this.state.activeTab} renderTab={this.renderTab} tabs={this.tabs} onTabPress={newTab => { this.setState({ activeTab: newTab.key }); }} />
                        : null
                }

            </View>
        );
    }

    componentWillMount() {
        this.keyboardDidShowListener = Keyboard.addListener('keyboardDidShow', this._keyboardDidShow.bind(this));
        this.keyboardDidHideListener = Keyboard.addListener('keyboardDidHide', this._keyboardDidHide.bind(this));
    }

    componentWillUnmount() {
        this.keyboardDidShowListener.remove();
        this.keyboardDidHideListener.remove();
    }

    _keyboardDidShow() {
        //alert('Keyboard Shown');
        this.setState({ showFooter: false })
    }

    _keyboardDidHide() {
        //alert('Keyboard Hidden');
        this.setState({ showFooter: true })
    }
    componentDidMount() {
        printLogs('call', 'componentDidMount')
        const { setParams } = this.props.navigation;
        setParams({ myProps: 'test' });
    }
}

Here is my Custom Drawer in which i want to access setSelectedPos() from Home tab click

export default class Custom_Side_Menu extends React.Component {

static navigationOptions = { hidenavigation };
state = {
    current_selected: 0
}


setSelectedPos(pos) {
    this.setState({ current_selected: pos });
}

closeNavigationPanel(pos) {
    if (pos != 3) {
        this.props.navigation.closeDrawer();
    }
}
redirectToProfile() {
    new NavigationRedirection().goToNextScreen('profile', this.props);
}
selectedColor(pos) {
    if (this.state.current_selected === pos) {
        return COLOR.input_text_color;
    } else {
        return COLOR.input_hint_color;
    }
}
render() {
    return (
        <ScrollView>
            <View style={stylePage.bg}>
                {/* */}

                <View style={{ flex: 1 }}>
                    <View style={{ padding: 10, alignContent: 'center', flexDirection: 'row', alignItems: 'center' }}>
                        <TouchableOpacity onPress={() => { this.closeNavigationPanel() }}>
                            <Icon name="arrow-left" size={30} color={COLOR.input_text_color} />
                        </TouchableOpacity>
                        <Text style={stylePage.menu_title}>Menu</Text>
                    </View>
                    <TouchableWithoutFeedback onPress={() => {
                        this.redirectToProfile();
                    }}>
                        <View>
                            <Image style={stylePage.profileImage} source={{ uri: 'https://uinames.com/api/photos/female/22.jpg' }} />
                            <Text style={stylePage.name}>Ruth McCoy</Text>
                            <Text style={stylePage.email}>ruth.mccoy@example.com</Text>
                        </View>
                    </TouchableWithoutFeedback>
                    <View style={stylePage.line_seprator} />
                    <View style={stylePage.menu_options}>
                        <Text style={[stylePage.menu_text, { color: this.selectedColor(0) }]} onPress={() => this.setCurrentSelection(0)}>Dashboard</Text>
                        <Text style={[stylePage.menu_text, { color: this.selectedColor(1) }]} onPress={() => this.setCurrentSelection(1)}>Diamonds List</Text>
                        <Text style={[stylePage.menu_text, { color: this.selectedColor(2) }]} onPress={() => this.setCurrentSelection(2)}>Add diamonds</Text>
                        <Text style={[stylePage.menu_text, { color: this.selectedColor(3) }]} onPress={() => this.setCurrentSelection(3)}>Profile</Text>
                        <Text style={[stylePage.menu_text, { color: this.selectedColor(4) }]} onPress={() => this.setCurrentSelection(4)}>Change Password</Text>
                    </View>
                </View>
                <TouchableOpacity style={{ alignSelf: 'baseline' }} onPress={() => clearAllData(this.props)}>
                    <View style={stylePage.logout_btn}>
                        <IconAnt name="logout" size={25} color={COLOR.white} />
                        <Text style={stylePage.logout_title}>Logout</Text>
                    </View>
                </TouchableOpacity>

                <RBSheet
                    closeOnDragDown={true}
                    closeOnPressMask={false}
                    ref={ref => { this.RBSheet = ref }}
                    height={getScreenHeight() / 2} duration={250} customStyles={{
                        container: { padding: 10, borderTopLeftRadius: 20, borderTopRightRadius: 20 },
                    }}>
                    <ChangePassword {...this.props} RBSheet={this.RBSheet} />
                </RBSheet>
            </View>
        </ScrollView>
    );
}

setCurrentSelection(pos) {
    this.closeNavigationPanel(pos);
    this.setSelectedPos(pos);
    if (pos === 3) {
        this.redirectToProfile();
    } else if (pos === 4) {
        this.RBSheet.open();
    } else {
        printLogs('props', this.props.navigation)
    }
}

}

Divyata Chauhan
  • 279
  • 4
  • 21

1 Answers1

0

There are two problems.

  1. Click on drawer options to change the navigation tab
  2. On tab change set the option as active

using redux as global store There is an easy way out if you need redux as your global store. first connect your components with react-redux connect

manage the activeTab state in store instead of component state

then on click of drawer option change the state in redux for your activetab this way you are able to solve the problem 1

Also make sure you check activetab from store if matched you can update the styling for active option in drawer . So here is solution for problem 2

Using tab navigator from react-navigation another option is using tabNavigator from react-navigation itself that way you only need to call navigator function for changing tab and getting the active tab from navigation state

* alternate to redux * you can use react context apis for managing your parent state if you are not using redux

Harish Jangra
  • 381
  • 5
  • 16