Logo

dev-resources.site

for different kinds of informations.

`useBackButton` hook to handle back button behavior in React Native

Published at
8/12/2019
Categories
reactnative
hooks
react
customhooks
Author
farskid
Author
7 person written this
farskid
open
`useBackButton` hook to handle back button behavior in React Native

React hooks help with carrying stateful logic and keeping their lifecycle separate from the view layer lifecycle. They've been around since React v16.8 and since people have been avoiding class components in favor of hooks.

One of the somewhat interesting aspects of hooks is their flexibility in terms of composition and abstraction. If a code snippet using different built-in hooks is handling a part of logic that is separate and independent from other parts, it can be abstracted away as a Custom Hook.

useBackButton custom hook

To handle the behavior of hardware back button in Android and tvOS devices using React Native, there is BackHandler API that can assist in overriding the default behavior or patching it.

BackHandler takes an event-driven approach to offer an API, meaning that to subscribe to back button presses, you'll need to register an event listener.

import { BackHandler } from "react-native";

function backButtonHandler() {}

BackHandler.addEventListener("hardwareBackPress", backButtonHandler);
Enter fullscreen mode Exit fullscreen mode

and of course, to de-register this subscription, you'll need to use removeListener, the same way we do so handling DOM events.

backButtonHandler.removeEventListener("hardwareBackPress", backButtonHandler);
Enter fullscreen mode Exit fullscreen mode

use Hooks to utilize BackHandler

Subscriptions are side effects! therefore, we can use useEffect built-in hook to execute them. It's important to notice that useEffect requires us to return a function to remove the subscription once React is willing to clean up! Cleanups are usual when the component is being unmounted or one of the dependencies of the useEffect hook change, so React needs to clean up previous subscriptions of that hook and re-execute it!

Read more about subscriptions and cleanups in useEffect

function backButtonHandler() {}

function MyComponent() {
  useEffect(() => {
    BackHandler.addEventListener("hardwareBackPress", backButtonHandler);

    return () => {
      BackHandler.removeEventListener("hardwareBackPress", backButtonHandler);
    };
  }, [backButtonHandler]);

  return <View>...</View>;
}
Enter fullscreen mode Exit fullscreen mode

useBackButton is born!

while the above code snippet works perfectly, copy-pasting it into all the screens might sound frustrating to some of us (we're freaks after all)! To help to remove our frustrations, React offers a way to build your custom hook.

/* ComponentA */
function backButtonHandlerForA() {}
function ComponentA() {
  // Frustration begins!
  useEffect(() => {
    BackHandler.addEventListener("hardwareBackPress", backButtonHandlerForA);

    return () => {
      BackHandler.removeEventListener(
        "hardwareBackPress",
        backButtonHandlerForA
      );
    };
  }, [backButtonHandlerForA]);

  return <ViewA />;
}

/* ComponentB */
function backButtonHandlerForB() {}
function ComponentB() {
  // Frustration begins!
  useEffect(() => {
    BackHandler.addEventListener("hardwareBackPress", backButtonHandlerForB);

    return () => {
      BackHandler.removeEventListener(
        "hardwareBackPress",
        backButtonHandlerForB
      );
    };
  }, [backButtonHandlerForB]);

  return <ViewB />;
}
Enter fullscreen mode Exit fullscreen mode

A custom hook is just an abstraction to share the same logic between components and hooks, the same way we do this between functions in a regular programming.
Components are functions. Hooks are functions as well. You get the idea, right?!

In cases of ComponentA and ComponentB samples above, registration, removal and hook implementation are the same. it's just the handlers that can be different per component. So our custom hook needs to provide those common parts and only accept the changing part (handler per component) as an incoming argument.

/* useBackButton */
function useBackButton(handler) {
  // Frustration isolated! Yay! 🎉
  useEffect(() => {
    BackHandler.addEventListener("hardwareBackPress", handler);

    return () => {
      BackHandler.removeEventListener(
        "hardwareBackPress",
        handler
      );
    };
  /* now that the handler is an external dependency, once handler 
    changes, we wanna be able to reflect that change and update the 
    handler inside our hook too. so we need to pass handler as a 
    dependency to our custom hook
  */
  }, [handler]);
}

/* ComponentA */
function backButtonHandlerForA() {}
function ComponentA() {
  // utilize custom hook
  useBackButtton(backButtonHandlerForA);
  return <ViewA />;
}

/* ComponentB */
function backButtonHandlerForB() {}
function ComponentB() {
  // utilize custom hook
  useBackButtton(backButtonHandlerForB);

  return <ViewB />;
}
Enter fullscreen mode Exit fullscreen mode

Recap

If you intend to share a common logic between components and built-in hooks, you can abstract that away by building your custom hook. Make sure to read the impressively detailed docs of Hooks and Rules of Hooks from the official docs.

Cheers!

customhooks Article's
29 articles in total
Favicon
Mastering Navigation Control in React with useCallbackPrompt and useBlocker 🚦
Favicon
Custom Hooks in React: Reusing Logic Across Components
Favicon
Fixing UI Update Issues with Custom Hooks in React
Favicon
Custom Hooks in React: A Guide to Creation and Usage
Favicon
React: leveraging custom hooks to extract reusable logic
Favicon
Custom Hooks
Favicon
Custom Hooks in React
Favicon
Mobile Orientation (React-Native)
Favicon
Reusing Logic in React with Custom Hooks: a Practical guide
Favicon
Harnessing Firebase in React with Custom Hooks: A Practical Guide
Favicon
Building Powerful React Components with Custom Hooks
Favicon
React Custom Hooks (useNetworkStatus)
Favicon
React Custom Hooks (useMediaPermission)
Favicon
React Custom Hooks (useDebounce)
Favicon
How to Create a Counter App with useReducer and Custom Hooks
Favicon
How to create custom Hooks in React.Js?
Favicon
React Slideshow Component with autoplay, fullscreen mode and expand all
Favicon
React Portals: create and open modals with keyboard keys
Favicon
Learn Something on React JSX and Hooks
Favicon
How to create Tabs in ReactJs using Hooks ?
Favicon
Simple hook to handle featue flags
Favicon
React custom hooks to update form data
Favicon
useIpAdrress()
Favicon
Custom hook useScroll.tsx :: React TypeScript
Favicon
useQuery() with React Router Dom
Favicon
React Custom Hooks
Favicon
useGeoPosition Hook - A Custom React Hook to grab latitude and longitude from a given address.
Favicon
`useBackButton` hook to handle back button behavior in React Native
Favicon
Form in Modal using React hooks – mistakes and lesson learnt

Featured ones: