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

Issues with Android's hardware back button with Tabs #3184

Closed
dextermb opened this issue Aug 15, 2018 · 15 comments
Closed

Issues with Android's hardware back button with Tabs #3184

dextermb opened this issue Aug 15, 2018 · 15 comments
Labels
android Specific to Android feature request

Comments

@dextermb
Copy link
Contributor

dextermb commented Aug 15, 2018

Version

Tell us which versions you are using:

  • react-native-router-flux 4.0.0-beta.27 (v3 is not supported)
  • react-native 0.54.0

Expected behaviour

When navigating to a Scene outside of Tabs from within tabs and then pressing the hardware back button, you should then be navigated back to the previous scene within tabs.

Actual behaviour

When navigating to a scene outside of tabs from within tabs and then pressing the hardware back button it navigates you to the last visited page outside of tabs. Ignoring the scene within tabs which was previously visited.

Steps to reproduce

For non-obvious bugs, please fork this component, modify Example project to reproduce your issue and include link here.

  1. Create a similar router to the example below
  2. Navigate to page_2
  3. Then navigate to page_3
  4. Press hardware back button
  5. You will end up on page_1

Minimal example router:

<Router>
    <Drawer key={'root'} contentComponent={...}>
        <Scene key={'page_1'} initial={true} component={...}/>
        <Scene key={'page_3'} component={...}/>

        <Tabs>
            <Scene key={'page_2'} component={...}/>
        </Tabs>
    </Drawer>
</Router>

Edit: Now seeing the same issues on react-native-router-flux 4.0.2

@dextermb dextermb reopened this Aug 15, 2018
@daviscabral
Copy link
Collaborator

Could you try with most recent version and let me know if is still broken?

@dextermb
Copy link
Contributor Author

@daviscabral, will test tomorrow

@dextermb
Copy link
Contributor Author

@daviscabral #3198

@daviscabral
Copy link
Collaborator

Please update your React and React Native versions and also try to use aksonov/react-native-router-flux while version 4.0.2 is not released to see if that is fixed.

@dextermb
Copy link
Contributor Author

I had attempted to do with previously with React 16.4.2 and React Native 0.54.0, but alas, no luck as the application wouldn't even launch

@daviscabral
Copy link
Collaborator

Those versions aren't compatible like I told you in the other ticket. About the hardware back button - that also happens with React Navigation when the POP action is called. That seems like a good enhancement to me.

I don't have time now to work on that, but if someone else decide to take stab ;-)

@dextermb
Copy link
Contributor Author

dextermb commented Aug 23, 2018

@daviscabral Thanks for helping me work through this. We're slowing making progress. I'm now using react-native-router-flux off master.

While I am still having the original problem of the software back button still skipping views, I've also noticed that tapping through the tabbar, and pressing back, will take you to the first tab. Not the previously selected ones.

<Router>
    <Drawer key={'root'} contentComponent={...}>
        <Tabs>
            <Scene key={'page_1'} initial={true} component={...}/>
            <Scene key={'page_2'} component={...}/>
            <Scene key={'page_3'} component={...}/>
        </Tabs>
    </Drawer>
</Router>

Going from page_1 to 2 then 3, hitting the back button will take you back to page_1 rather than 2. Any ideas?

@daviscabral
Copy link
Collaborator

That's because of the navigator reference that is used. The default back action is dispatched from there, what causes the nested navigators to be ignored. To fix that you will need to override the back handler from your Router.

@dextermb
Copy link
Contributor Author

Interesting. @daviscabral, you'd suggest keeping my own stack of views and then just going back to the previous one?

Does the onStateChange prop work for Router, this way I could get the current route and push it whenever navigation happens?

@dextermb
Copy link
Contributor Author

This does not seem to get triggered 😨

export default class App extends React.Component {
	render() {
		return (
			<Router 
			    scenes={Routes} 
			    onStateChange={() => console.warn('changed')}
			/>
		);
	}
}

@daviscabral
Copy link
Collaborator

Check the Example, it's working there 👍

2018-08-23 06 58 45

@dextermb
Copy link
Contributor Author

dextermb commented Aug 23, 2018

@daviscabral yeah, haha. Good stuff! I think this thread can be closed now 🎉 Thanks again.

I'll come up with a nice example for the back button and update the docs.

@dextermb
Copy link
Contributor Author

dextermb commented Aug 23, 2018

class App extends React.Component {
	constructor() {
		super();

		this.state = {};
		this.state.routes = [Actions.currentScene.replace('_', '')];
		this.state.logged_in = false;
	}

	async onStateChange() {
		const route = Actions.currentScene.replace('_', '');
		const routes = this.state.routes;

		if (route !== routes[routes.length - 1]) {
			routes.push(route);

			console.warn('pushed', routes);

			await this.setState({ routes });
		}
	}

	async hardwareBackPress() {
		const { routes, logged_in } = this.state;

		if (!!routes.length) {
			const last_route = routes[routes.length - 2];

			if (logged_in && last_route === 'Login') {
				return true;
			}

			routes.pop();

			await this.setState({ routes });


			Actions[last_route]();
		}

		return true;
	}

	componentDidMount() {
		Auth.isAuthenticated().then(logged_in => this.setState({ logged_in }));

		BackAndroid.addEventListener('hardwareBackPress', () => this.hardwareBackPress());
	}

	componentWillMount() {
		BackAndroid.removeEventListener('hardwareBackPress', () => this.hardwareBackPress());
	}

	render() {
		return (
			<Router scenes={Routes} onStateChange={() => this.onStateChange()}/>
		);
	}
}

@daviscabral Here's what I am doing to make the back button work as expected 😸

@daviscabral
Copy link
Collaborator

I will keep this opened to track the PR that I might work in the weekend to make it easier.

@daviscabral daviscabral reopened this Aug 24, 2018
@daviscabral daviscabral added feature request android Specific to Android and removed enhancement labels Aug 29, 2018
@daviscabral
Copy link
Collaborator

I believe a custom reducer also can make it work without needing to change the lib. I am inclined to close this issue since the lib is flexible enough to allow a proper fix. What do you think?

@aksonov aksonov closed this as completed Sep 28, 2018
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
android Specific to Android feature request
Projects
None yet
Development

No branches or pull requests

3 participants