/
AccountContext.tsx
55 lines (50 loc) · 1.38 KB
/
AccountContext.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
import {
createContext,
DependencyList,
Dispatch,
ReactNode,
SetStateAction,
useCallback,
useContext,
useEffect,
useState,
} from "react";
import { Account, restoreAccount } from "../lib/account";
import { getEvents } from "../lib/api";
type ContextValue = {
accounts: { [accountId: string]: Account };
setAccounts: Dispatch<SetStateAction<{ [accountId: string]: Account }>>;
};
const AccountContext = createContext<ContextValue>({
accounts: {},
setAccounts: () => {},
});
type Props = {
children: ReactNode;
};
export function AccountContextProvider({ children }: Props): JSX.Element {
const [accounts, setAccounts] = useState({});
return (
<AccountContext.Provider value={{ accounts, setAccounts }}>
{children}
</AccountContext.Provider>
);
}
export function useAccount(
accountId: string,
deps: DependencyList
): [Account | null, (account: Account) => void] {
const { accounts, setAccounts } = useContext(AccountContext);
const setAccount = (account: Account) => {
setAccounts((accounts) => ({ ...accounts, [accountId]: account }));
};
useEffect(() => {
const cachedAccount = accounts[accountId];
if (cachedAccount === undefined) {
getEvents(accountId)
.then((events) => restoreAccount(events))
.then((account) => setAccount(account));
}
}, deps);
return [accounts[accountId] ?? null, setAccount];
}