-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathuse-lazy-ref.ts
31 lines (27 loc) · 891 Bytes
/
use-lazy-ref.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
29
30
31
import {useRef} from 'react';
// Opaque type that is not null
// (we want to be able to pass null as an init)
const SENTINEL = {};
/**
* Creates a ref that can be initalized with a callback (lazily).
* This is useful so we don't have to construct a class or call a function every time we
* call this hook in a component as that could be costly.
*
* Inspiration is from https://github.com/facebook/react/issues/14490
*
* @param init Initial value
* @returns A React ref that was initalized with `init`
*
* @example
* const ref = useLazyRef(() => new MyExpensiveClass());
* ref.current.doSomething();
*/
export function useLazyRef<T>(init: () => T) {
const ref = useRef<T | typeof SENTINEL>(SENTINEL);
if (ref.current === SENTINEL) {
ref.current = init();
}
// Guarenteed to be a non-sentinel value
// so the cast is safe :)
return ref as React.MutableRefObject<T>;
}