-
-
Notifications
You must be signed in to change notification settings - Fork 5.3k
/
Copy pathuseEventCallback.ts
28 lines (24 loc) · 1013 Bytes
/
useEventCallback.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import * as React from 'react';
import { useCallback } from 'react';
// allow the hook to work in SSR
const useLayoutEffect =
typeof window !== 'undefined' ? React.useLayoutEffect : React.useEffect;
/**
* Alternative to useCallback that doesn't update the callback when dependencies change
*
* @see https://reactjs.org/docs/hooks-faq.html#how-to-read-an-often-changing-value-from-usecallback
* @see https://github.com/facebook/react/issues/14099#issuecomment-440013892
*/
export const useEventCallback = <Args extends unknown[], Return>(
fn: (...args: Args) => Return,
dependencies: any[]
): ((...args: Args) => Return) => {
const ref = React.useRef<(...args: Args) => Return>(() => {
throw new Error('Cannot call an event handler while rendering.');
});
useLayoutEffect(() => {
ref.current = fn;
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [fn, ...dependencies]);
return useCallback((...args: Args) => ref.current(...args), []);
};