function useRecoilValueLoadable_TRANSITION_SUPPORT()

in packages/recoil/hooks/Recoil_Hooks.js [425:485]


function useRecoilValueLoadable_TRANSITION_SUPPORT<T>(
  recoilValue: RecoilValue<T>,
): Loadable<T> {
  const storeRef = useStoreRef();
  const componentName = useComponentName();

  // Accessors to get the current state
  const getLoadable = useCallback(() => {
    if (__DEV__) {
      recoilComponentGetRecoilValueCount_FOR_TESTING.current++;
    }
    const store = storeRef.current;
    const storeState = store.getState();
    const treeState = reactMode().early
      ? storeState.nextTree ?? storeState.currentTree
      : storeState.currentTree;
    return getRecoilValueAsLoadable(store, recoilValue, treeState);
  }, [storeRef, recoilValue]);
  const getState = useCallback(
    () => ({loadable: getLoadable(), key: recoilValue.key}),
    [getLoadable, recoilValue.key],
  );

  // Memoize state snapshots
  const updateState = useCallback(
    prevState => {
      const nextState = getState();
      return prevState.loadable.is(nextState.loadable) &&
        prevState.key === nextState.key
        ? prevState
        : nextState;
    },
    [getState],
  );

  // Subscribe to Recoil state changes
  useEffect(() => {
    const subscription = subscribeToRecoilValue(
      storeRef.current,
      recoilValue,
      _state => {
        setState(updateState);
      },
      componentName,
    );

    // Update state in case we are using a different key
    setState(updateState);

    return subscription.release;
  }, [componentName, recoilValue, storeRef, updateState]);

  // Get the current state
  const [state, setState] = useState(getState);

  // If we changed keys, then return the state for the new key.
  // This is important in case the old key would cause the component to suspend.
  // We don't have to set the new state here since the subscribing effect above
  // will do that.
  return state.key !== recoilValue.key ? getState().loadable : state.loadable;
}