├── .github
└── FUNDING.yml
├── .gitignore
├── BackHandler.android.js
├── BackHandler.ios.js
├── BackHandler.web.js
├── LICENSE
├── README.md
├── index.d.ts
├── index.js
└── package.json
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: [vonovak]
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 | yarn-debug.log*
6 | yarn-error.log*
7 |
8 | # Runtime data
9 | pids
10 | *.pid
11 | *.seed
12 | *.pid.lock
13 |
14 | # Directory for instrumented libs generated by jscoverage/JSCover
15 | lib-cov
16 |
17 | # Coverage directory used by tools like istanbul
18 | coverage
19 |
20 | # nyc test coverage
21 | .nyc_output
22 |
23 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
24 | .grunt
25 |
26 | # Bower dependency directory (https://bower.io/)
27 | bower_components
28 |
29 | # node-waf configuration
30 | .lock-wscript
31 |
32 | # Compiled binary addons (http://nodejs.org/api/addons.html)
33 | build/Release
34 |
35 | # Dependency directories
36 | node_modules/
37 | jspm_packages/
38 |
39 | # Typescript v1 declaration files
40 | typings/
41 |
42 | # Optional npm cache directory
43 | .npm
44 |
45 | # Optional eslint cache
46 | .eslintcache
47 |
48 | # Optional REPL history
49 | .node_repl_history
50 |
51 | # Output of 'npm pack'
52 | *.tgz
53 |
54 | # Yarn Integrity file
55 | .yarn-integrity
56 |
57 | # dotenv environment variables file
58 | .env
59 |
60 |
--------------------------------------------------------------------------------
/BackHandler.android.js:
--------------------------------------------------------------------------------
1 | import { useCallback } from 'react';
2 | import { BackHandler } from 'react-native';
3 | import { useFocusEffect } from '@react-navigation/native';
4 |
5 | export const useAndroidBackHandler = (onBackPress) => (
6 | useFocusEffect((
7 | useCallback(() => {
8 | const subscription = BackHandler.addEventListener('hardwareBackPress', onBackPress);
9 |
10 | return () => subscription.remove();
11 | }, [onBackPress])
12 | ))
13 | );
14 |
15 | export const AndroidBackHandler = ({ onBackPress, children = null }) => {
16 | useAndroidBackHandler(onBackPress);
17 |
18 | return children;
19 | };
20 |
--------------------------------------------------------------------------------
/BackHandler.ios.js:
--------------------------------------------------------------------------------
1 | export const AndroidBackHandler = ({ children }) => children || null;
2 | export const useAndroidBackHandler = () => {};
3 |
--------------------------------------------------------------------------------
/BackHandler.web.js:
--------------------------------------------------------------------------------
1 | export const AndroidBackHandler = ({ children }) => children || null;
2 | export const useAndroidBackHandler = () => {};
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2018 Vojtech Novak
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # react-navigation-backhandler
2 |
3 | Easily handle Android back button behavior with React-Navigation.
4 |
5 | > NOTE use version 1 of this package for `react-navigation` version 4 and lower
6 | >
7 | > use version 2 of this package for `react-navigation` version 5 and later
8 |
9 | ## Installation
10 |
11 | Install with npm:
12 |
13 | ```sh
14 | $ npm install react-navigation-backhandler
15 | ```
16 |
17 | Install with yarn:
18 |
19 | ```sh
20 | $ yarn add react-navigation-backhandler
21 | ```
22 |
23 | ## Usage
24 |
25 | The following snippet demonstrates the usage. Note that `onBackButtonPressAndroid` will only be called if `SomeComponent` is placed in a screen that is focused (the one user is directly interacting with).
26 |
27 | Behind the scenes, the `onBackButtonPressAndroid` handler is registered before a screen is focused, and unregistered before going away from it, leaving you with a declarative interface to interact with. Internally, this package uses apis that are provided by `react-navigation`.
28 |
29 | You may use `useAndroidBackHandler` or `AndroidBackHandler` component anywhere in your app's React tree, it does not need to be placed directly in the screen component.
30 |
31 | There are two ways of using this library:
32 |
33 | 1. [As hook](#use-as-hook)
34 | 1. [As component](#use-as-component)
35 |
36 | ### Use as hook
37 |
38 | ```js
39 | import { useAndroidBackHandler } from "react-navigation-backhandler";
40 |
41 | const SomeComponent = () => {
42 | const onBackPress = useCallback(() => {
43 | /*
44 | * Returning `true` denotes that we have handled the event,
45 | * and react-navigation's lister will not get called, thus not popping the screen.
46 | *
47 | * Returning `false` will cause the event to bubble up and react-navigation's listener will pop the screen.
48 | * */
49 |
50 | if (youWantToHandleTheBackButtonPress) {
51 | // do something
52 | return true
53 | }
54 |
55 | return false
56 | }, [])
57 |
58 | useAndroidBackHandler(onBackPress)
59 |
60 | return
61 | }
62 | ```
63 |
64 | ### Use as component
65 |
66 | > **Note:** You can also use the component "inline" without children: ``
67 |
68 | ```js
69 | import { AndroidBackHandler } from "react-navigation-backhandler";
70 |
71 | class SomeComponent extends React.Component {
72 | onBackButtonPressAndroid = () => {
73 | /*
74 | * Returning `true` from `onBackButtonPressAndroid` denotes that we have handled the event,
75 | * and react-navigation's lister will not get called, thus not popping the screen.
76 | *
77 | * Returning `false` will cause the event to bubble up and react-navigation's listener will pop the screen.
78 | * */
79 |
80 | if (youWantToHandleTheBackButtonPress) {
81 | // do something
82 | return true;
83 | }
84 |
85 | return false;
86 | };
87 |
88 | render() {
89 | return (
90 |
91 |
92 |
93 | );
94 | }
95 | }
96 | ```
97 |
98 | ## Warning
99 |
100 | The package was only tested to be used in screens in stack navigator, other use cases may not work.
101 |
--------------------------------------------------------------------------------
/index.d.ts:
--------------------------------------------------------------------------------
1 | declare module "react-navigation-backhandler" {
2 | import { FC, PropsWithChildren } from "react";
3 |
4 | export interface AndroidBackHandlerProperties {
5 | onBackPress: () => boolean;
6 | }
7 |
8 | export const AndroidBackHandler: FC>;
9 |
10 | export function useAndroidBackHandler(onBackPress: () => boolean): void;
11 | }
12 |
--------------------------------------------------------------------------------
/index.js:
--------------------------------------------------------------------------------
1 | export * from './BackHandler';
2 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-navigation-backhandler",
3 | "version": "2.0.3",
4 | "description": "Easily handle Android back button with react-navigation",
5 | "main": "index.js",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "git+https://github.com/vonovak/react-navigation-backhandler.git"
12 | },
13 | "keywords": [
14 | "react-navigation",
15 | "react-native"
16 | ],
17 | "peerDependencies": {
18 | "react": "*",
19 | "@react-navigation/native": "*",
20 | "react-native": "*"
21 | },
22 | "author": "Vojtech Novak",
23 | "license": "MIT",
24 | "bugs": {
25 | "url": "https://github.com/vonovak/react-navigation-backhandler/issues"
26 | },
27 | "homepage": "https://github.com/vonovak/react-navigation-backhandler#readme"
28 | }
29 |
--------------------------------------------------------------------------------