DEV Community

Alexander Goncharuk for This is Learning

Posted on

Wrap your library in a React hook

This is the third and last article in a series on designing a Javascript library for different frameworks to use. In the first article in the series, we have built a vanilla TS/JS library for swipe detection in the browser. Although it can be used in your application built with any popular JS framework as is, we want to go a little further and make our library a first-class citizen when used in the framework of your choice.

In this article, we are going to wrap our swipe detection library in a React hook.

💡 The article implies you are familiar with the public interface of the swipe detection library used under the hood. If you haven't read the first article in the series, this section alone will be enough to follow along with the material of this one.

How should it work

We want to wrap the swipe detection functionality of the underlying library in a reusable React hook. Let's call one useSwipe as it is important to follow the hooks naming convention. This is how the hook will be used in a consumer component:

const swipeElement = useSwipe({
  onSwipeEnd: (event: SwipeEvent) => {
    console.log(`SwipeEnd direction: ${event.direction} and distance: ${event.distance}`);
  }
});

return <div ref={swipeElement}>Swipe me!</div>
Enter fullscreen mode Exit fullscreen mode

Complete solution

The wrapper hook will be quite concise:

import { createSwipeSubscription, SwipeSubscriptionConfig } from 'ag-swipe-core';
import { RefCallback, useCallback } from 'react';
import { Subscription } from 'rxjs';

export const useSwipe = (config: Pick<SwipeSubscriptionConfig, 'onSwipeMove' | 'onSwipeEnd'>): RefCallback<HTMLElement> => {
  let swipeSubscription: Subscription | undefined;

  return useCallback((domElement: HTMLElement) => {
    if (domElement) {
      swipeSubscription = createSwipeSubscription({
        domElement,
        ...config
      });
    } else {
      swipeSubscription?.unsubscribe?.();
    }
  }, []);
}
Enter fullscreen mode Exit fullscreen mode

What we want from the hook is:

  • get a reference to the DOM element the swipe listener should be attached.
  • react to one being mounted/unmounted to perform subscription and unsubscription tasks correspondingly.

Our first intention could be to use a combination of useRef and useEffect hooks, but what we actually need is a combination of ref and useCallback:

... the callback ref will be called only when the component mounts and unmounts

Couldn't ask for a better fit. If the domElement parameter value coming from ref is truthy i.e. component has been mounted, we call createSwipeSubscription with provided onSwipeMove and/or onSwipeEnd handlers. If the value is falsy i.e. the component has been unmounted, we use the swipeSubscription reference to unsubscribe.

To learn more on how ref and useCallback work together see this section in React documentation.

Wrapping up

You can find the complete library code on GitHub by this link.

And the npm package by this link.

That was it! We have built a simple React hook wrapper for our swipe detection library in 17 lines of code.

This article completes our short series. Thanks for reading and stay tuned!

Top comments (0)