All files useMappedState.ts

89.29% Statements 25/28
40% Branches 2/5
84.62% Functions 11/13
91.67% Lines 22/24

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 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83                                                                    29x 29x   29x   9x 10x           10x         29x 70x 61x     29x 21x 21x     29x 29x       29x 9x 21x   9x         29x 11x 11x     29x    
import * as React from 'react';
import { StateGetter } from './types';
import { Store } from './Store';
 
export function useMappedState<T1, R>(
  stateGetters: [StateGetter<T1>],
  mapper: (state1: T1) => R,
  deps?: any[]
): R;
export function useMappedState<T1, T2, R>(
  stateGetters: [StateGetter<T1>, StateGetter<T2>],
  mapper: (state1: T1, state2: T2) => R,
  deps?: any[]
): R;
export function useMappedState<T1, T2, T3, R>(
  stateGetters: [StateGetter<T1>, StateGetter<T2>, StateGetter<T3>],
  mapper: (state1: T1, state2: T2, state3: T3) => R,
  deps?: any[]
): R;
export function useMappedState<T1, T2, T3, T4, R>(
  stateGetters: [
    StateGetter<T1>,
    StateGetter<T2>,
    StateGetter<T3>,
    StateGetter<T4>
  ],
  mapper: (state1: T1, state2: T2, state3: T3, state4: T4) => R,
  deps?: any[]
): R;
export function useMappedState(
  stateGetters: Array<StateGetter<any>>,
  mapper: (...args: any[]) => any,
  deps: any[] = []
) {
  const mapperCached = React.useCallback(mapper, deps);
  const [, forceUpdate] = React.useReducer(x => x + 1, 0);
 
  const stores = React.useMemo(
    () =>
      stateGetters.map((getter: any) => {
        Iif (!getter._store) {
          throw new Error(
            `_store not found in getter for module "${getter._module ||
              'unknown'}". Make sure to load the module before using 'useState' or 'useMappedState'.`
          );
        }
        return getter._store as Store;
      }),
    []
  );
 
  const getMappedState = () => {
    const states = stores.map(store => store.state);
    return mapperCached(...states);
  };
 
  const getSubscribeFn = () => {
    stateRef.current = getMappedState();
    forceUpdate({});
  };
 
  const stateRef = React.useRef(getMappedState());
  const subscribeRef = React.useRef(getSubscribeFn);
 
  // subscribe to stored immediately
  // React.useEffect can sometimes miss updates
  React.useLayoutEffect(() => {
    const subscriptions = stores.map(store =>
      store.subscribe(() => subscribeRef.current())
    );
    return () => {
      subscriptions.forEach(subscription => subscription());
    };
  }, []);
 
  React.useMemo(() => {
    stateRef.current = getMappedState();
    subscribeRef.current = getSubscribeFn;
  }, deps);
 
  return stateRef.current;
}