use-effect-event
shadcn-hooks/use-effect-eventFreeHook
A hook to declare an effect event
Install it
npx shadcn@latest add https://shadcn-hooks.com/r/use-effect-event.jsonSource
1import * as React from 'react'2import { createContext, useCallback, useInsertionEffect, useRef } from 'react'34const context = createContext(true)56function forbiddenInRender() {7 throw new Error(8 "A function wrapped in useEffectEvent can't be called during rendering.",9 )10}1112// We can only check if we're in a render phase, beyond initial render, in React 19, with its `React.use` hook.13const isInvalidExecutionContextForEventFunction =14 'use' in React15 ? () => {16 // 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-L178817 // So to emulate the same behavior, we call the use hook and if it doesn't throw, we're in a render phase.18 try {19 return React.use(context)20 } catch {21 return false22 }23 }24 : () => false2526/**27 * This is a ponyfill of the upcoming `useEffectEvent` hook that'll arrive in React 19.28 * https://19.react.dev/learn/separating-events-from-effects#declaring-an-effect-event29 * To learn more about the ponyfill itself, see: https://blog.bitsrc.io/a-look-inside-the-useevent-polyfill-from-the-new-react-docs-d1c4739e807230 * @public31 */32export function useEffectEvent<const T extends (...args: any[]) => void>(33 fn: T,34): T {35 /**36 * For both React 18 and 19 we set the ref to the forbiddenInRender function, to catch illegal calls to the function during render.37 * Once the insertion effect runs, we set the ref to the actual function.38 */39 const ref = useRef(forbiddenInRender as T)4041 useInsertionEffect(() => {42 ref.current = fn43 }, [fn])4445 return useCallback((...args: any) => {46 // Performs a similar check to what React does for `useEffectEvent`:47 // 1. https://github.com/facebook/react/blob/b7e2de632b2a160bc09edda1fbb9b8f85a6914e8/packages/react-reconciler/src/ReactFiberHooks.js#L2729-L273348 // 2. https://github.com/facebook/react/blob/b7e2de632b2a160bc09edda1fbb9b8f85a6914e8/packages/react-reconciler/src/ReactFiberHooks.js#L2746C9-L275049 if (isInvalidExecutionContextForEventFunction()) {50 forbiddenInRender()51 }5253 const latestFn = ref.current!54 return latestFn(...args)55 }, []) as T56}
Files it writes
More from shadcn-hooks
All 58 items| Component | Registry | Kind | Access | Installs | Command |
|---|---|---|---|---|---|
| use-active-elementuse-active-element | shadcn-hooks | Hooks | Free | no deps | |
| use-batteryuse-battery | shadcn-hooks | Hooks | Free | no deps | |
| use-booleanuse-boolean | shadcn-hooks | Hooks | Free | no deps | |
| use-click-any-whereuse-click-any-where | shadcn-hooks | Hooks | Free | no deps | |
| use-click-awayuse-click-away | shadcn-hooks | Hooks | Free | no deps | |
| use-clipboarduse-clipboard | shadcn-hooks | Hooks | Free | no deps | |
| use-controllable-valueuse-controllable-value | shadcn-hooks | Hooks | Free | 1 dep | |
| use-counteruse-counter | shadcn-hooks | Hooks | Free | no deps |
