如何在自定义抽屉中调用父组件函数

时间:2020-03-18 05:49:09

标签: react-native react-navigation-drawer

我是React Native的初学者。我陷入一个问题。我有一个父组件Home.js,在其中单击选项卡3子组件会根据所选键替换选项卡导航器。在同一页面中,我有自定义抽屉。现在,我想在单击自定义抽屉选项时更改选项卡,而当我的第一个选项卡选择了抽屉的第一个选项时也设置了选择。我该如何做到这一点。

这是我的导航抽屉:

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

这是我要在自定义抽屉中访问goToNextTab()的Home类

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' });
    }
}

这是我的自定义抽屉,我要在其中通过“主页”选项卡单击访问setSelectedPos()

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)
    }
}

}

1 个答案:

答案 0 :(得分:0)

有两个问题。

  1. 单击抽屉选项以更改导航选项卡
  2. 在选项卡更改中将选项设置为活动

使用redux作为全局存储 如果您需要redux作为全局存储,则有一个简单的解决方法。 首先将您的组件与react-redux connect

连接

管理存储区中的activeTab状态而不是组件状态

然后单击“抽屉”选项,为您的activetab更改redux中的状态 这样您就可以解决问题1

还要确保从商店中检查activetab(如果匹配),则可以更新抽屉中active选项的样式。所以这是问题2的解决方案

从反应导航中使用标签导航器 另一个选择是从react-navigation本身使用tabNavigator,这样您只需要调用导航功能来更改tab 并从导航状态获取活动标签

*替代redux * 如果您不使用redux,则可以使用react上下文api来管理您的父状态