Custom hook in React to track page views

We will create a custom hook in React that will help us track how many times have the page is viewed on client side (in the browser). You can use this to track how many times a component as mounted or any other activity.

To create this hook, we will rely on the localforage (indexDB), you can also use localStorage, it is upto you.

The logic is simple, we will use a key as a unique identifier to track the page or the component. Against this key we will add an entry into the localForage every time the component mounts using useEffect() hook.

Before adding the value to the storage, we will pull the last value and increment the count if it exists or make a fresh entry to it.

import { useEffect, useCallback, useState, useMemo } from 'react';

// Utils
import localforage from 'localforage';

export const useTrackPageViews = (key: string) => {
  const [pageViews, setPageViews] = useState(null);

  const getDefaultValue = useCallback(async () => {
    try {
      const value = await localforage.getItem(key);
      await localforage.setItem(key, (value ?? 0) + 1);
      setPageViews(value ?? 0);
    } catch (e) {
      setPageViews(0);
    }
  }, [setPageViews, key]);

  useEffect(() => {
    getDefaultValue();
  }, [key]);

  const _pageViews = useMemo(() => {
    return { pageViews };
  }, [pageViews]);

  return _pageViews;
};

Here we have created a function getDefaultValue() which is wrapped inside the useCallback that will be updated only when the key changes.

Similar the value is wrapped inside the useMemo() as I am returning an object here which will trigger re-rendering as the referential equality will change. You can just return the variable as value and avoid using useMemo().

You can use useRef as a variable rather than useState to avoid triggering re-rendering.