All files / libs/ext/react/hooks/src/lib/use-state-with-ref useStateWithRef.ts

100% Statements 38/38
80% Branches 4/5
100% Functions 2/2
100% Lines 38/38

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 391x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 12x 12x 12x 12x 12x 12x 12x 12x 12x 12x 6x 6x 6x 6x 12x 12x 12x 12x  
import { useCallback, useRef, useState, type Dispatch, type SetStateAction } from 'react';
 
const isStateFn = <S>(setStateAction: SetStateAction<S>): setStateAction is (prevState: S) => S =>
  typeof setStateAction === 'function';
 
type ReadOnlyRefObject<T> = {
  readonly current: T;
};
 
export function useStateWithRef<S>(
  initialState: S | (() => S),
): [state: S, setState: Dispatch<SetStateAction<S>>, stateRef: ReadOnlyRefObject<S>];
 
export function useStateWithRef<S = undefined>(): [
  state: S | undefined,
  setState: Dispatch<SetStateAction<S | undefined>>,
  stateRef: ReadOnlyRefObject<S | undefined>,
];
 
export function useStateWithRef<S>(
  initialState?: S | (() => S),
): [
  state: S | undefined,
  setState: Dispatch<SetStateAction<S | undefined>>,
  stateRef: ReadOnlyRefObject<S | undefined>,
] {
  const [state, setState] = useState(initialState);
  const stateRef = useRef(state);
 
  const handleChange: typeof setState = useCallback((newValue) => {
    setState((currentValue) => {
      stateRef.current = isStateFn(newValue) ? newValue(currentValue) : newValue;
      return stateRef.current;
    });
  }, []);
 
  return [state, handleChange, stateRef];
}