{
  "name": "use-effect-event",
  "author": "Brendan Dash (https://shadcn-hooks.com)",
  "description": "A hook to declare an effect event",
  "files": [
    {
      "path": "registry/hooks/use-effect-event.ts",
      "content": "import * as React from 'react'\nimport { createContext, useCallback, useInsertionEffect, useRef } from 'react'\n\nconst context = createContext(true)\n\nfunction forbiddenInRender() {\n  throw new Error(\n    \"A function wrapped in useEffectEvent can't be called during rendering.\",\n  )\n}\n\n// We can only check if we're in a render phase, beyond initial render, in React 19, with its `React.use` hook.\nconst isInvalidExecutionContextForEventFunction =\n  'use' in React\n    ? () => {\n        // There's no way to check if we're in a render phase from outside of React, the API used by useEffectEvent is private: https://github.com/facebook/react/blob/a00ca6f6b51e46a0ccec54a2231bfe7a1ed9ae1d/packages/react-reconciler/src/ReactFiberWorkLoop.js#L1785-L1788\n        // So to emulate the same behavior, we call the use hook and if it doesn't throw, we're in a render phase.\n        try {\n          return React.use(context)\n        } catch {\n          return false\n        }\n      }\n    : () => false\n\n/**\n * This is a ponyfill of the upcoming `useEffectEvent` hook that'll arrive in React 19.\n * https://19.react.dev/learn/separating-events-from-effects#declaring-an-effect-event\n * To learn more about the ponyfill itself, see: https://blog.bitsrc.io/a-look-inside-the-useevent-polyfill-from-the-new-react-docs-d1c4739e8072\n * @public\n */\nexport function useEffectEvent<const T extends (...args: any[]) => void>(\n  fn: T,\n): T {\n  /**\n   * For both React 18 and 19 we set the ref to the forbiddenInRender function, to catch illegal calls to the function during render.\n   * Once the insertion effect runs, we set the ref to the actual function.\n   */\n  const ref = useRef(forbiddenInRender as T)\n\n  useInsertionEffect(() => {\n    ref.current = fn\n  }, [fn])\n\n  return useCallback((...args: any) => {\n    // Performs a similar check to what React does for `useEffectEvent`:\n    // 1. https://github.com/facebook/react/blob/b7e2de632b2a160bc09edda1fbb9b8f85a6914e8/packages/react-reconciler/src/ReactFiberHooks.js#L2729-L2733\n    // 2. https://github.com/facebook/react/blob/b7e2de632b2a160bc09edda1fbb9b8f85a6914e8/packages/react-reconciler/src/ReactFiberHooks.js#L2746C9-L2750\n    if (isInvalidExecutionContextForEventFunction()) {\n      forbiddenInRender()\n    }\n\n    const latestFn = ref.current!\n    return latestFn(...args)\n  }, []) as T\n}\n",
      "type": "registry:hook"
    }
  ],
  "type": "registry:hook"
}
