-
Notifications
You must be signed in to change notification settings - Fork 9
Expand file tree
/
Copy pathuseClientRef.tsx
More file actions
58 lines (50 loc) · 2.09 KB
/
useClientRef.tsx
File metadata and controls
58 lines (50 loc) · 2.09 KB
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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
import { createClient, IAuthClient } from "@propelauth/javascript"
import { MutableRefObject, useCallback, useEffect, useRef, useState } from "react"
type ClientRef = {
authUrl: string
client: IAuthClient
}
interface UseClientRefProps {
authUrl: string
minSecondsBeforeRefresh?: number
}
export const useClientRef = (props: UseClientRefProps) => {
const [accessTokenChangeCounter, setAccessTokenChangeCounter] = useState(0)
const { authUrl, minSecondsBeforeRefresh } = props
// Use a ref to store the client so that it doesn't get recreated on every render
const clientRef = useRef<ClientRef | null>(null)
if (clientRef.current === null) {
const client = createClient({ authUrl, enableBackgroundTokenRefresh: true, minSecondsBeforeRefresh, skipInitialFetch: true })
client.addAccessTokenChangeObserver(() => setAccessTokenChangeCounter((x) => x + 1))
clientRef.current = { authUrl, client }
}
// If the authUrl changes, destroy the old client and create a new one
useEffect(() => {
if (clientRef.current === null) {
return
} else if (clientRef.current.authUrl === authUrl) {
return
} else {
clientRef.current.client.destroy()
const newClient = createClient({ authUrl, enableBackgroundTokenRefresh: true, minSecondsBeforeRefresh, skipInitialFetch: true })
newClient.addAccessTokenChangeObserver(() => setAccessTokenChangeCounter((x) => x + 1))
clientRef.current = { authUrl, client: newClient }
}
}, [authUrl])
return { clientRef, accessTokenChangeCounter }
}
export const useClientRefCallback = <I extends unknown[], O>(
clientRef: MutableRefObject<ClientRef | null>,
callback: (client: IAuthClient) => (...inputs: I) => O
): ((...inputs: I) => O) => {
return useCallback(
(...inputs: I) => {
const client = clientRef.current?.client
if (!client) {
throw new Error("Client is not initialized")
}
return callback(client)(...inputs)
},
[callback]
)
}