Skip to content

Latest commit

 

History

History
290 lines (219 loc) · 6.05 KB

README.md

File metadata and controls

290 lines (219 loc) · 6.05 KB

react hooks helpers

A collection of utility hooks to problems I've solved over the years.

npm version

Getting Started

Install dependencies

$ npm install

Development

Run storybook:

$ npm run dev
  • storybook will be running at http://localhost:6006

Build storybook static files:

$ npm run storybook:build

Run unit tests:

$ npm run test

Run unit tests in watch mode:

$ npm run test:watch

Run linter check:

$ npm run lint:check

Run linter auto fix:

$ npm run lint:fix

Run prettier check:

$ npm run format:check

Run prettier write:

$ npm run format:write

Run production build:

$ npm run build

Library


useAsyncScript

  • A stateful hook for asynchronously loading 3rd party scripts in the browser. For example reCAPTCHA or google maps.

Example:

const url = 'https://example.com/?default=true';

export function AsyncScriptExample(): JSX.Element | null {
  const { loading, done } = useAsyncScript(url);

  if (loading) {
    return <>Loading...</>;
  }

  if (done) {
    return <>Script complete</>;
  }

  if (error) {
    return <>Script errored</>;
  }

  return null;
}

useBreakpoint

  • A hook that returns the current breakpoint according to the browser's window size.

Example:

export function BreakpointExample(){
  const breakpoint = useBreakpoint();

  return (
    <div>
      <div>{`Current breakpoint is: ${breakpoint}`}</div>
    </div>
  );
}
  • also supports a config to set custom breakpoints
export function CustomConfigExample(){
  const config = {
    xsmall: { end: 300 },
    small: { start: 300, end: 500 },
    large: { start: 500 },
  };
  
  const breakpoint = useBreakpoint(config);

  return (
    <div>
      <div>{`Current breakpoint is: ${breakpoint}`}</div>
    </div>
  );
}

useComposedRefs

  • A hook to combine multiple instances of a ref into 1 instance to pass to an element.

Example:

const ForwardedRefComponent = forwardRef<HTMLElement, PropsWithChildren<{}>>(
  (props, forwardedRef) => {
    const internalRef = useRef<HTMLDivElement | null>(null);
    const ref = useComposedRefs(internalRef, forwardedRef);

    return (
      <div ref={ref}>
        {props.children}
      </div>
    );
  }
);

useControlledReducer

  • a low level hook that utilizes inversion of control and allows you to define a default reducer, and also allows for consumer to override state changes, and state values through props. Useful if you want a state that could be controlled or uncontrolled depending on the consumer props being passed in.

See an example implementation of a headless select hook that utilizes this hook.


useOutsideClick

  • A hook that will execute a callback when a click occurs outside of an element.

Example:

function OutsideClickExample(){
  const callback = (): void => {
    alert('Clicked outside of the button');
  };
  const ref = useOutsideClick(callback);

  return (
      <button ref={ref}>Click outside of me</button>
  );
}

usePrevious

  • A hook that will keep track of the previous state of a stateful value.

Example:

export function PreviousStateExample() {
  const [count, setCount] = useState(0);
  const previousState = usePrevious(count);

  function increaseCount() {
    setCount(prevState => prevState + 1);
  }

  function decreaseCount() {
    setCount(prevState => {
      const nextState = prevState - 1;
      return nextState < 0 ? 0 : nextState;
    });
  }

  return (
    <div>
      <button onClick={increaseCount}>Increase</button>
      <button onClick={decreaseCount}>Decrease</button>

      <div>
        {`Counter: ${count}`}
        
        <div>{`Previous count: ${previousState}`}</div>
      </div>
    </div>
  );
}

useRect

  • A hook that returns the current DOMRect measurements for a DOM element

Example:

function DOMRectExample(){
  const ref = useRef<HTMLDivElement | null>(null);
  const rect = useRect(ref);

  console.log(rect);

  return (
    <div ref={ref}>
      My DOMRect will be tracked
    </div>
  )
}

useSubscription

  • a hook for subscribing to external data sources.
import { useMemo } from 'react';
import debounce from 'lodash.debounce';

import { useSubscription } from '../useSubscription/useSubscription';

export function useWindowWidth(): number {
  const source = window;
  const subscription = useMemo(
    () => ({
      getCurrentValue: () => source.innerWidth,
      subscribe: (callback: any) => {
        source.addEventListener('resize', debounce(callback, 300));
        return () => source.removeEventListener('resize', callback);
      },
    }),
    [source.innerWidth]
  );
  return useSubscription(subscription);
}

useWindowWidth

  • A hook that returns the current width of the browser window.

Example:

export function WindowWidthExample() {
  const width = useWindowWidth();

  return <div>{`Window's width is ${width}px`}</div>;
}