Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

default BackHandler from child <Scene> is stacked on top of root BackHandler from <Drawer> causing problems with drawer's state management #3045

Closed
rayj10 opened this issue May 22, 2018 · 2 comments

Comments

@rayj10
Copy link

rayj10 commented May 22, 2018

Version

Tell us which versions you are using:

  • react-native-router-flux v4.0.0-beta.28

Expected behaviour

default BackHandler from newly stacked drawer tab shouldn't be of higher priority than the root BackHandler implemented in drawer component

Actual behaviour

when new scene stacked on the current scene (i.e. when I move using Actions.settingTab() from Home) from it seems that there is a new default BackHandler being attached to that scene (setting) with a default behaviour of Actions.pop(), The only way I can think of to override this is to add backHandler to every scene which is counter-intuitive of what I'm trying to achieve (BackHandler centralized in the drawer to handle any hardware back button press on any scene other than login scene).

Steps to reproduce

So here is the routes I'm working with:

<Router>
                <Scene key="root" hideNavBar>
                    <Stack key="Auth" initial={!this.state.isLoggedIn}>
                        <Scene key="Login" hideNavBar component={Login} title="Login" />
                    </Stack>
                    <Stack key="Main" initial={this.state.isLoggedIn}>
                        <Scene drawer key="NavDrawer" hideNavBar contentComponent={() => <NavDrawer username={this.state.userName} />} type={ActionConst.REPLACE} panHandlers={null}>
                            <Scene key="homeTab" navBar={() => <PageHeader title='Home' />} drawerLockMode={'locked-closed'}>
                                <Scene tabs={true} tabBarComponent={ScrollableTabBar} tabBarPosition='top' lazy={true}>
                                    <Scene key="Home" hideNavBar component={Home} title={"Home"} name='Home'/>
                                </Scene>
                                <Scene key="itemDescription" hideNavBar component={itemDescription} title="Item Description" back />
                            </Scene>
                            <Scene key="helpTab" navBar={() => <PageHeader title='Help' />} title="Help" drawerLockMode={'locked-closed'}>
                                <Scene>
                                    <Scene key="Help" hideNavBar component={Help} title={"Help"} />
                                </Scene>
                            </Scene>
                            <Scene key="settingTab" navBar={() => <PageHeader title='Settings' />} title="Settings" drawerLockMode={'locked-closed'}>
                                <Scene>
                                    <Scene key="Setting" hideNavBar component={Setting} title={"Setting"} />
                                </Scene>
                            </Scene>
                            <Scene key="QRTab" navBar={() => <PageHeader title='QR Scanner' />} title="QR" drawerLockMode={'locked-closed'}>
                                <Scene>
                                    <Scene key="QRScanner" hideNavBar component={QRScanner} title={"QR Scanner"} />
                                </Scene>
                            </Scene>
                        </Scene>
                    </Stack>
                </Scene>
            </Router>

and this is the BackHandler from my NavDrawer:

handleBackButton() {
        if (Actions.currentScene === '_Home')
            this.onSignOut()
        else if (this.state.currentTab !== 'Home') {
            this.setState({ currentTab: 'Home' })
            Actions.homeTab();
        }
        else{
            Actions.pop();
            console.log('popped')
        }
        return true;
    }

    componentDidMount() {
        BackHandler.addEventListener('hardwareBackPress', this.handleBackButton);
    }

    componentWillUnmount() {
        BackHandler.removeEventListener('hardwareBackPress');
    }

At this point all the logical scene movements are working as expected, however, due to the default BackHandler being called and just doing Actions.pop() to get back to Home, the tab highlight is not moved back to Home because setState({currentTab:'Home'}) was never called.

Any Idea on how to disable to default handler or to do a workaround without adding individual backhandler to each scene in the tab?

@rayj10
Copy link
Author

rayj10 commented May 22, 2018

UPDATE: turns out this problem only occurs when I'm auto logged in (i.e. skipped the Auth stack and straight into the Main stack), it seems something went wrong between the reloading and componentWillUnmount or componentDidMount not being called and BackHandlers from previous reloads collide somehow.

Because if I try this scenario:

login --> Setting/Help/QR tab --> hardware back to Home it doesn't cause the problem

but if I do:

autoLogin(login using stored token) --> Setting/Help/QR tab --> hardware back to Home the default BackHandler will be called, but if I press back once again, the desired BackHandler is called and I'm logged out, then if I try to login again, everything works perfectly!

Hope this helps narrowing down my problem

@rayj10 rayj10 closed this as completed May 22, 2018
@rayj10
Copy link
Author

rayj10 commented May 22, 2018

not related to RNRF, problem was with componentDidMount called again after hot reloading without componentWillUnmount ever called causing listener stack to act weird.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant