简体   繁体   English

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

[英]How to call Parent component function inside custom drawer

I am beginner in React Native.我是 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.我有一个父组件 Home.js,其中有选项卡导航器,单击选项卡 3 子组件时会根据所选键替换。 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这是我的 Home 类,我想在自定义抽屉中访问 goToNextTab()

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这是我的自定义抽屉,我想在其中访问 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)
    }
}

} }

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.使用 redux 作为全局存储如果您需要将 redux 作为全局存储,有一个简单的方法。 first connect your components with react-redux connect首先使用react-redux connect连接你的组件

manage the activeTab state in store instead of component state管理 store 中的 activeTab 状态而不是组件状态

then on click of drawer option change the state in redux for your activetab this way you are able to solve the problem 1然后单击抽屉选项更改您的 activetab 在 redux 中的状态,这样您就可以解决问题 1

Also make sure you check activetab from store if matched you can update the styling for active option in drawer .还要确保您从商店检查 activetab 如果匹配,您可以更新 drawer 中 active 选项的样式。 So here is solution for problem 2所以这是问题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使用 react-navigation 中的 tab navigator另一个选项是使用 react-navigation 中的 tabNavigator 这样你只需要调用 navigator 函数来更改选项卡并从导航状态获取活动选项卡

* alternate to redux * you can use react context apis for managing your parent state if you are not using redux * 替代 redux *如果您不使用 redux,您可以使用 react context apis 来管理您的父状态

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM