/
auth.context.tsx
58 lines (48 loc) 路 1.57 KB
/
auth.context.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
import React, {
createContext,
ReactNode,
useContext,
useEffect,
useState,
} from 'react';
import { AXIOS_INSTANCE } from './api/mutator/custom-instance';
type Dispatch = (Auth: string) => void;
type AuthProviderProps = { children: ReactNode; initialState?: string | null };
const AuthContext = createContext<string | null>(null);
const AuthDispatchContext = createContext<Dispatch | null>(null);
const AuthProvider = ({ children, initialState = null }: AuthProviderProps) => {
// it's a quick demo with useState but you can also have a more complexe state with a useReducer
const [token, setToken] = useState(initialState);
useEffect(() => {
const interceptorId = AXIOS_INSTANCE.interceptors.request.use((config) => ({
...config,
headers: token
? {
...config.headers,
Authorization: `Bearer ${token}`,
}
: config.headers,
}));
return () => {
AXIOS_INSTANCE.interceptors.request.eject(interceptorId);
};
}, [token]);
return (
<AuthContext.Provider value={token}>
<AuthDispatchContext.Provider value={setToken}>
{children}
</AuthDispatchContext.Provider>
</AuthContext.Provider>
);
};
const useAuth = (): string | null => {
return useContext<string | null>(AuthContext);
};
const useAuthDispatch = (): Dispatch => {
const context = useContext<Dispatch | null>(AuthDispatchContext);
if (context === null) {
throw new Error('useAuthDispatch must be used within a AuthProvider');
}
return context;
};
export { AuthProvider, useAuth, useAuthDispatch };