React-Query
기존에는 Redux 를 사용해서 전역관리를 하고 있었습니다.
그러던 중 사이드 프로젝트에서 Redux 를 사용해서 코드를 작성하려니 굉장히 많은 보일러 플레이트 코드를 작성하는게 아찔하게 느껴지더라고요..
하라면 하겠지만 즐겁게 하고 싶었던 사이드 프로젝트에서 그러고 싶진 않아서 평소 관심이 있던 React-Query 를 사용하기로 했습니다.
설치
Getting Started 기준으로 진행합니다.
yarn add react-query
QueryClientProvider 로 리엑트 앱을 감싸줍니다.
import React from 'react';
import { QueryClient, QueryClientProvider } from 'react-query';
import { ChakraProvider } from '@chakra-ui/react'
import Routers from './routes';
import theme from './utils/theme';
const queryClient = new QueryClient();
const App = () => {
return (
<QueryClientProvider client={queryClient}>
<ChakraProvider theme={theme}>
<Routers />
</ChakraProvider>
</QueryClientProvider>
)
};
export default App;
디버깅 툴을 붙여줍니다.
import React from 'react';
import { QueryClient, QueryClientProvider } from 'react-query';
import { ReactQueryDevtools } from 'react-query/devtools'; // 추가 코드
import { ChakraProvider } from '@chakra-ui/react'
import Routers from './routes';
import theme from './utils/theme';
const queryClient = new QueryClient();
const App = () => {
return (
<QueryClientProvider client={queryClient}>
<ChakraProvider theme={theme}>
<Routers />
</ChakraProvider>
<ReactQueryDevtools initialIsOpen={false} /> {/* 추가 코드 */}
</QueryClientProvider>
)
};
export default App;
그러면 하단에 이렇게 아이콘이 뜨는데 클릭하면 디버깅 툴이 뜹니다.
네트워크 통신을 위해 axios 를 설치합니다.
yarn add axios
사용
사용하려고 했던 로그인 로직을 예제를 참고해 login.tsx 에 구현해봅니다.
먼저 다음 링크를 참고한 axios 설정을 합니다.
src/api/index.ts
import axios, { AxiosResponse } from 'axios';
import { UserType } from '../models/user.interface';
const baseUrl = process.env.SERVER_URL || 'http://localhost:3000/';
const instance = axios.create({
baseURL: baseUrl,
timeout: 15000,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
}
});
const authInstance = (jwt: string) => axios.create({
baseURL: baseUrl,
timeout: 15000,
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json',
'Authorization': jwt
}
});
const responseBody = (response: AxiosResponse<{}>) => response;
export const requests = {
get: (url: string, jwt: string) => authInstance(jwt).get(url).then(responseBody),
post: (url: string, body: {}, jwt: string) => authInstance(jwt).post(url, body).then(responseBody),
patch: (url: string, body: {}, jwt: string) => authInstance(jwt).put(url, body).then(responseBody),
delete: (url: string, jwt: string) => authInstance(jwt).delete(url).then(responseBody),
};
export const User = {
login: (user: UserType) => instance.post('login', user)
}
src/models/user.interface.ts
export interface UserType {
id?: number;
name?: string;
email: string;
password?: string;
authorization?: string;
}
로그인, 회원가입 API 의 경우에는 Authorization 을 필요로 하지 않기 때문에 index.ts 안에서 작성했고 그 외의 API 들은 Authorization 이 필요해 외부에 작성할 예정 입니다.
이제 로그인 API 를 적용해 봅시다.
const queryClient = useQueryClient();
const mutation = useMutation(
userinfo => User.login({ email: userinfo.email, password: userinfo.password }), {
onMutate: async (user: UserType) => {
const previousTodos = queryClient.getQueryData<UserType>('user');
return { previousTodos };
},
onSuccess: (response, variables, context) => {
console.log(response.headers);
queryClient.setQueryData<UserType>('user', response.data);
},
onError: (err, variables, context) => {
if (context?.previousTodos) {
queryClient.setQueryData<UserType>('user', context.previousTodos);
}
},
onSettled: () => {
queryClient.invalidateQueries('user')
},
});
useEffect(() => {
mutation.mutate({ email: 'tjstlr2010@gmail.com', password: 'qwer1234' });
}, []);
결과 값 리턴이 재대로 되는걸 확인 할 수 있었지만 CORS 가 터졌습니다 ㅋㅋㅋㅋ
CORS 수정 후 인증 값이 저장 됩니다.