Skip to content

Instantly share code, notes, and snippets.

@ymulenll
Forked from diegohaz/useEvent.tsx
Created September 22, 2022 20:40
Show Gist options
  • Select an option

  • Save ymulenll/c79f8cc8df4605924481883abfd73c45 to your computer and use it in GitHub Desktop.

Select an option

Save ymulenll/c79f8cc8df4605924481883abfd73c45 to your computer and use it in GitHub Desktop.
type AnyFunction = (...args: any[]) => any
function useEvent<T extends AnyFunction>(callback?: T) {
const ref = useRef<AnyFunction | undefined>(() => {
throw new Error("Cannot call an event handler while rendering.")
})
useLayoutEffect(() => {
ref.current = callback
})
return useCallback<AnyFunction>(
(...args) => ref.current?.apply(null, args),
[]
) as T
}
// Usage
function Component(props) {
const [visible, setVisible] = useState(false)
// props.onToggle may not be stable
const onToggle = useEvent(props.onToggle)
// But our onToggle is stable
useEffect(() => onToggle(visible), [onToggle, visible])
// ❌ Throws when used in the render phase
onToggle(visible)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment