iTwin / react-hooks

common, generic, useful react hooks for general high-level react development
MIT License
5 stars 0 forks source link

add useLoadingSemaphore hook #13

Open MichaelBelousov opened 3 years ago

MichaelBelousov commented 3 years ago

/**
 * a custom hook that makes it easier to manage
 * a loading state with multiple consumers that can
 * declare they are loading, such as a component waiting
 * on two separate network requests. Returns whether isLoading,
 * and a `startLoading` and `finishLoading` function to wrap around critical sections like so:
 * @example
 * useEffect(() => {
 *   startLoading();
 *   await networkFetch();
 *   finishLoading();
 * }, []);
 */
export function useLoadingSemaphore() {
  const [loadingSemaphore, setLoadingSemaphore] = React.useState(0);
  // use useRef to stabilize the references (ok since setLoadingSemaphore is guaranteed stable)
  const startLoading = React.useRef(() => setLoadingSemaphore((p) => p + 1))
    .current;
  const finishLoading = React.useRef(() => setLoadingSemaphore((p) => p - 1))
    .current;
  const isLoading = loadingSemaphore > 0;
  return {
    isLoading,
    startLoading,
    finishLoading,
  };
}

this hook is generic and useful, should consider it for adding