File tree 3 files changed +62
-3
lines changed
3 files changed +62
-3
lines changed Original file line number Diff line number Diff line change 46
46
"use-is-client" : {},
47
47
"use-isomorphic-layout-effect" : {},
48
48
"use-retimer" : {},
49
+ "use-singleton" : {},
49
50
"use-stable-handler-only-when-you-know-what-you-are-doing-or-you-will-be-fired" : {
50
51
"title" : " useStableHandler"
51
52
},
Original file line number Diff line number Diff line change
1
+ ---
2
+ title : useSingleton
3
+ ---
4
+
5
+ # useSingleton
6
+
7
+ import ExportMetaInfo from ' ../components/export-meta-info' ;
8
+
9
+ <ExportMetaInfo />
10
+
11
+ The React documentation's [ "Avoiding recreating the ref contents" pattern] ( https://react.dev/reference/react/useRef#avoiding-recreating-the-ref-contents ) as a hook.
12
+
13
+ ** Before:**
14
+
15
+ ``` tsx
16
+ function Video() {
17
+ const playerRef = useRef (null );
18
+ if (playerRef .current === null ) {
19
+ playerRef .current = new VideoPlayer ();
20
+ }
21
+ // ...
22
+ ` ` `
23
+
24
+ **After:**
25
+
26
+ ` ` ` tsx
27
+ function Video() {
28
+ const playerRef = useSingleton (() => new VideoPlayer ());
29
+ // ...
30
+ ` ` `
31
+
32
+ ## Usage
33
+
34
+ ` ` ` tsx copy
35
+ import { useCallback , useEffect } from ' react' ;
36
+ import { useSingleton } from ' foxact/use-singleton' ;
37
+
38
+ interface VideoProps {
39
+ videoSrc: string ;
40
+ }
41
+
42
+ function Video({ videoSrc }: VideoProps ) {
43
+ const playerRef = useSingleton (() => new VideoPlayer ());
44
+
45
+ // callback ref to attach the player to the video element
46
+ const videoElementCallbackRef = useCallback ((el : HTMLVideoElement | null ) => {
47
+ if (el ) {
48
+ playerRef .current .attach (el );
49
+ playerRef .current .load (videoSrc );
50
+ } else {
51
+ playerRef .current .destroy ();
52
+ }
53
+ }, [videoSrc ]);
54
+
55
+ return <video ref = { videoElementCallbackRef } />;
56
+ }
57
+ ` ` `
58
+
59
+
Original file line number Diff line number Diff line change @@ -6,17 +6,16 @@ export interface SingletonRefObject<T> {
6
6
readonly current : T
7
7
}
8
8
9
+ /** @see https://foxact.skk.moe/use-singleton */
9
10
export const useSingleton = < T > ( initializor : ( ) => T ) : SingletonRefObject < T > => {
10
11
const r = useRef < T > ( ) ;
11
-
12
- // eslint-disable-next-line @typescript-eslint/no-unnecessary-condition -- it will be undefined only on first render
13
12
if ( ! r . current ) {
14
13
r . current = initializor ( ) ;
15
14
}
16
15
17
16
// We are using singleton approach here, to prevent repeated initialization.
18
17
// The value will only be written by the hook during the first render and it
19
- // should not be written by anyone else
18
+ // should not be written by anyone else anymore
20
19
// @ts -expect-error -- see above
21
20
return r ;
22
21
} ;
You can’t perform that action at this time.
0 commit comments