맛집 앱 만들기 프로젝트 Part14 React Query 로그인연동하기
React Query 사용을 위해 Query Client Provider로 App을 감싸주자
[matzip/front/App.tsx]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import {NavigationContainer} from '@react-navigation/native';
import React from 'react';
import RootNavigator from './src/navigations/root/RootNavigator';
import {QueryClientProvider} from '@tanstack/react-query';
import queryClient from './src/api/queryClient';
function App() {
return (
<QueryClientProvider client={queryClient}>
<NavigationContainer>
<RootNavigator />
</NavigationContainer>
</QueryClientProvider>
);
}
export default App;
queryClient 파일 코드 작성
[matzip/front/src/api/queryClient.ts]
QueryClientProvider로 App을 감싸주었는데 QueryClientProvider 사용을 위해서는 client라는 속성을 사용해야하고 client속성은 따로 파일로 분리하도록한다
React Query 는 기본적으로 서버의 재요청을 3번을 하는것을 기본으로하는데 해당 요청을 하지 않는 옵션으로 retry들을 모두 false로준다
1
2
3
4
5
6
7
8
9
10
11
12
13
14
import {QueryClient} from '@tanstack/react-query';
const queryClient = new QueryClient({
defaultOptions: {
queries: {
retry: false,
},
mutations: {
retry: false,
},
},
});
export default queryClient;
[matzip/front/src/hooks/useAuth.ts]
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
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import {
QueryKey,
UseQueryOptions,
useMutation,
useQuery,
} from '@tanstack/react-query';
import {
getAccessToken,
getProfile,
logout,
postLogin,
postSignup,
} from '../../api/auth';
import {
ResponseError,
UseMutationCustomOptions,
UseQueryCustomOptions,
} from '../../types/common';
import {removeEncryptStorage, setEncryptStorage} from '../../utils';
import axiosInstance from '../../api/axios';
import {removeHeader, setHeader} from '../../utils/header';
import {useEffect} from 'react';
import queryClient from '../../api/queryClient';
function useSignup(mutationOptions?: UseMutationCustomOptions) {
return useMutation({
mutationFn: postSignup,
...mutationOptions,
});
}
function useLogin(mutationOptions?: UseMutationCustomOptions) {
return useMutation({
mutationFn: postLogin,
onSuccess: ({accessToken, refreshToken}) => {
setEncryptStorage('refreshToken', refreshToken);
setHeader('Authorization', `Bearer ${accessToken}`);
console.log(
`로그인성공 refreshToken값 : ${refreshToken} Authorization값 : ${accessToken}`,
);
axiosInstance.defaults.headers.common['Authorization'] = accessToken;
},
onSettled: () => {
queryClient.refetchQueries({queryKey: ['auth', 'getAccessToken']});
queryClient.invalidateQueries({queryKey: ['auth', 'getProfile']});
},
...mutationOptions,
});
}
function useGetRefreshToken() {
const {isSuccess, data, isError} = useQuery({
queryKey: ['auth', 'getAccessToken'],
queryFn: getAccessToken,
staleTime: 1000 * 60 * 30 - 1000 * 60 * 3,
refetchInterval: 1000 * 60 * 30 - 1000 * 60 * 3,
refetchOnReconnect: true,
refetchIntervalInBackground: true,
});
useEffect(() => {
if (isSuccess) {
setHeader('Authorization', `Bearer ${data.accessToken}`);
setEncryptStorage('refreshToken', data.refreshToken);
}
}, [isSuccess]);
useEffect(() => {
if (isError) {
removeHeader('Authorization');
removeEncryptStorage('refreshToken');
}
}, [isError]);
return {isSuccess, isError};
}
function useGetProfile(queryOptions?: UseQueryCustomOptions) {
return useQuery({
queryKey: ['auth', 'getProfile'],
queryFn: getProfile,
...queryOptions,
});
}
function useLogout(mutationOptions?: UseMutationCustomOptions) {
return useMutation({
mutationFn: logout,
onSuccess: () => {
removeHeader('Authorization');
removeEncryptStorage('refreshToken');
},
onSettled: () => {
queryClient.invalidateQueries({queryKey: ['auth']});
},
...mutationOptions,
});
}
function useAuth() {
const signupMutation = useSignup();
const refreshTokenQuery = useGetRefreshToken();
const getProfileQuery = useGetProfile({
enabled: refreshTokenQuery.isSuccess,
});
const isLogin = getProfileQuery.isSuccess;
const loginMutation = useLogin();
const logoutMutation = useLogout();
return {
signupMutation,
loginMutation,
isLogin,
getProfileQuery,
logoutMutation,
};
}
export default useAuth;
This post is licensed under
CC BY 4.0
by the author.