Skip to content

Instantly share code, notes, and snippets.

@ArnaudBarre
Last active July 29, 2025 10:34
Show Gist options
  • Select an option

  • Save ArnaudBarre/8367f3f9f104689a7f485aed676c8a77 to your computer and use it in GitHub Desktop.

Select an option

Save ArnaudBarre/8367f3f9f104689a7f485aed676c8a77 to your computer and use it in GitHub Desktop.
Set of react utils to work with callbacks and event listeners
export const useSyncRef = <T>(value: T) => {
const ref = useRef<T>(value);
ref.current = value;
return ref;
};
export const useSyncRefWithEffect = <T>(value: T) => {
const ref = useRef<T>(value);
useEffect(() => {
ref.current = value;
}, [value]);
return ref;
};
export const useStableCallback = <T extends (...args: any[]) => any>(cb: T) => {
const ref = useSyncRef<T>(cb);
return useCallback(((...args) => ref.current(...args)) as T, [ref]);
};
export const on = <E extends keyof WindowEventMap>(
type: E,
listener: (this: Window, ev: WindowEventMap[E]) => any,
useCapture?: boolean,
) => {
window.addEventListener(type, listener, useCapture);
return () => window.removeEventListener(type, listener, useCapture);
};
export const useOn = <E extends keyof WindowEventMap>(
type: E,
listener: (ev: WindowEventMap[E]) => any,
useCapture?: boolean,
) => {
const stableListener = useStableCallback(listener);
useEffect(
() => on(type, stableListener, useCapture),
[type, stableListener, useCapture],
);
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment