Skip to content

Instantly share code, notes, and snippets.

@finas
Forked from diegohaz/useEvent.tsx
Created March 29, 2023 05:45
Show Gist options
  • Save finas/532baab5bf9f7da2d2d4bd9e8276973e to your computer and use it in GitHub Desktop.
Save finas/532baab5bf9f7da2d2d4bd9e8276973e 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.")
})
// Or useInsertionEffect if it's React 18
useLayoutEffect(() => {
ref.current = callback
})
return useCallback<AnyFunction>((...args) => ref.current?.(...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