type AnyFunction = (...args: any[]) => any function useEvent(callback?: T) { const ref = useRef(() => { throw new Error("Cannot call an event handler while rendering.") }) // Or useInsertionEffect if it's React 18 useLayoutEffect(() => { ref.current = callback }) return useCallback((...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) }