-
Notifications
You must be signed in to change notification settings - Fork 40
/
Copy pathImportedController.tsx
48 lines (40 loc) · 1.5 KB
/
ImportedController.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
import React, { createContext, useCallback, useLayoutEffect, useState } from 'react';
interface ImportedState {
usesHydration: boolean;
pastHydration: boolean;
}
export const importedState = createContext<ImportedState | undefined>(undefined);
export const HydrationState: React.FC<{ state: ImportedState }> = ({ state, children }) => (
<importedState.Provider value={state}>{children}</importedState.Provider>
);
/**
* this component just creates a "the first-most" effect in the system
*/
const HydrationEffect = ({ loopCallback }: { loopCallback(): void }): null => {
useLayoutEffect(loopCallback, []);
return null;
};
/**
* @see [LazyBoundary]{@link LazyBoundary} - HydrationController is required for LazyBoundary to properly work with React>16.10
* Established a control over LazyBoundary suppressing fallback during the initial hydration
* @param props
* @param [props.usesHydration=true] determines of Application is rendered using hydrate
*/
export const ImportedController: React.FC<{
/**
* determines of Application is rendered using hydrate
*/
usesHydration?: boolean;
}> = ({ children, usesHydration = true }) => {
const [state, setState] = useState<ImportedState>({
usesHydration,
pastHydration: false,
});
const onFirstHydration = useCallback(() => setState((oldState) => ({ ...oldState, pastHydration: true })), []);
return (
<>
<HydrationEffect loopCallback={onFirstHydration} />
<HydrationState state={state}>{children}</HydrationState>
</>
);
};