'Is there any problem with this useSet react hook?

I created a hook for useSet because the npm package react-use has a useSet hook which destroys the set with every operation. I don't want to re-create the whole set each time I change one value.

What I thought I'd do is use a useState hook to trigger updates if the set contents changes by toggling the useState between true and false, then I would store the actual set in a useRef(). When updates are made to the set, I would call doUpdate() which toggles the update state true <-> false. No direct access to the mutable state is given, and there are accessor methods using useCallback(). Code follows:

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

export interface UseSetActions<K> {
  add: (key: K) => void;
  remove: (key: K) => void;
  toggle: (key: K) => void;
  reset: () => void;
  has: (key: K) => boolean;
}

const useSet = <K>(initialSet = new Set<K>()): UseSetActions<K> => {
  const set = useRef(initialSet);
  const [update, setUpdate] = useState(false);
  
  const doUpdate = useCallback(() => {
    setUpdate((prev) => !prev);
  }, []);

  const add = useCallback((item: K) => {
    if (!set.current.has(item)) {
      set.current.add(item);
      doUpdate();
    }
  }, [doUpdate]);

  const remove = useCallback((item: K) => {
    if (set.current.has(item)) {
      set.current.delete(item);
      doUpdate();
    }
  }, [doUpdate]);

  const toggle = useCallback((item: K) => {
    if (set.current.has(item)) {
      set.current.delete(item);
    } else {
      set.current.add(item);
    }
    doUpdate();
  }, [doUpdate]);

  const reset = useCallback(() => {
    set.current = new Set(initialSet);
    doUpdate();
  }, [doUpdate]);

  const has = useCallback((val: K): boolean => set.current.has(val), []);

  return {
    reset,
    has,
    add,
    remove,
    toggle,
  };
};

export default useSet;


Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source