-
-
Notifications
You must be signed in to change notification settings - Fork 94
/
Copy pathCacheProvider.tsx
69 lines (63 loc) · 1.89 KB
/
CacheProvider.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
58
59
60
61
62
63
64
65
66
67
68
69
import masterReducer, {
initialState as defaultState,
} from '@rest-hooks/core/state/reducer';
import NetworkManager from '@rest-hooks/core/state/NetworkManager';
import { State, Manager } from '@rest-hooks/core/types';
import useEnhancedReducer from '@rest-hooks/use-enhanced-reducer';
import React, { ReactNode, useEffect, useMemo } from 'react';
import { useRef } from 'react';
import {
StateContext,
DispatchContext,
DenormalizeCacheContext,
} from '../context';
interface ProviderProps {
children: ReactNode;
managers: Manager[];
initialState: State<unknown>;
}
/** Controller managing state of the REST cache and coordinating network requests. */
export default function CacheProvider({
children,
managers,
initialState,
}: ProviderProps) {
const denormalizeCache = useRef({
entities: {},
results: {},
});
const [state, dispatch] = useEnhancedReducer(
masterReducer,
initialState,
managers.map(manager => manager.getMiddleware()),
);
const optimisticState = useMemo(
() => state.optimistic.reduce(masterReducer, state),
[state],
);
// if we change out the manager we need to make sure it has no hanging async
useEffect(() => {
for (let i = 0; i < managers.length; ++i) {
managers[i].init?.(state);
}
return () => {
for (let i = 0; i < managers.length; ++i) {
managers[i].cleanup();
}
};
// eslint-disable-next-line react-hooks/exhaustive-deps
}, managers);
return (
<DispatchContext.Provider value={dispatch}>
<StateContext.Provider value={optimisticState}>
<DenormalizeCacheContext.Provider value={denormalizeCache.current}>
{children}
</DenormalizeCacheContext.Provider>
</StateContext.Provider>
</DispatchContext.Provider>
);
}
CacheProvider.defaultProps = {
managers: [new NetworkManager()] as Manager[],
initialState: defaultState as State<unknown>,
};