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 useEffec() 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 getDefaultValu() which is wrapped inside the useCallback() that will be updated only when the key changes.

Similar the value is wrapped inside the useMem() 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.