-
Notifications
You must be signed in to change notification settings - Fork 2
/
apollo-client-regenerator.tsx
57 lines (50 loc) · 2.38 KB
/
apollo-client-regenerator.tsx
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
import React, { memo, useState, useMemo, useEffect, useRef, useContext, useCallback } from 'react';
import { ApolloClient, ApolloProvider } from '@apollo/client';
import { generateApolloClient, IApolloClientGeneratorOptions } from '@deep-foundation/hasura/client';
import {debug} from './debug.js'
const moduleLog = debug.extend('apollo-client-regenerator')
export interface IApolloClientRegenerator {
options: IApolloClientGeneratorOptions;
children?: any;
useStateApolloClient?: (defaultValue: ApolloClient<any>) => [ApolloClient<any>, (apolloClient: ApolloClient<any>) => any];
regenerateApolloClient?: (options: IApolloClientGeneratorOptions) => ApolloClient<any>;
}
export const defaultRegenerateApolloClient = (options: IApolloClientGeneratorOptions): ApolloClient<any> => {
if (!generateApolloClient) throw new Error("!generateApolloClient");
return generateApolloClient(options);
};
interface IApolloClientGeneratorContext {
regenerate: () => any;
}
export const ApolloClientRegeneratorContext = React.createContext<IApolloClientGeneratorContext>({ regenerate: () => {} });
export function useApolloClientRegenerator() {
return useContext(ApolloClientRegeneratorContext);
}
/**
* Recreate ApolloClient on mount, and on each token or options changes. Make sure you memo it and dont update options object without need.
*/
export const ApolloClientRegenerator = memo<IApolloClientRegenerator>(function ApolloClientRegenerator({
options,
children = null,
useStateApolloClient = useState,
regenerateApolloClient = defaultRegenerateApolloClient,
}: IApolloClientRegenerator) {
const log = moduleLog.extend(ApolloClientRegenerator.name)
const initialApolloClient = useMemo(() => regenerateApolloClient(options), []);
log({initialApolloClient})
const [apolloClient, setApolloClient] = useStateApolloClient(initialApolloClient);
log({apolloClient, setApolloClient})
const mountedRef = useRef<boolean>(false);
useEffect(() => {
if (!mountedRef.current) mountedRef.current = true;
else setApolloClient(regenerateApolloClient(options));
}, [options]);
const context = useMemo(() => ({
regenerate: () => {
setApolloClient(regenerateApolloClient(options));
},
}), [options]);
return <ApolloClientRegeneratorContext.Provider value={context}>
<ApolloProvider client={apolloClient}>{children}</ApolloProvider>
</ApolloClientRegeneratorContext.Provider>;
});