React Query는 서버 상태 관리를 간단하고 효율적으로 할 수 있게 해주는 강력한 라이브러리이다
React Query는 제네릭 타입 형식으로 지원하고 있다
그래서 제네릭을 잘 사용한다면 타입을 보장 받으면서 편리하게 데이터를 다룰 수 있다 !
타입 지정을 안하면, 대부분 unknown, any 타입을 사용하고 있기 때문에 명시적으로 타입을 지정해서 비동기 상태의 타입 안정성을 확보하자
useQuery
useQuery 타입은 아래와 같다
export function useQuery<
TQueryFnData = unknown, // queryFn의 리턴 값
TError = unknown, // queryFn의 에러 형식
TData = TQueryFnData, // data
TQueryKey extends QueryKey = QueryKey
>
TQueryFnData , TError
queryFn의 리턴값
const { data, error } = useQuery<number, AxiosError>(['todo'], getTodo);
// data = number | undefined
// error = AxiosError | null
TData : data에 담기는 실질적 타입
선택 옵션이므로, queryFn 데이터를 2차 가공하는 경우에만 사용되는 타입 지정해주면 3번째 타입, 지정 안하면 TQueryFnData
const { data } = useQuery<Todo[], AxiosError, number>({
queryKey : ['todos'],
queryFn: getTodos,
select: todos => todos.length
});
// select로 todos의 length을 data에 담기로 했으니,
// 세 번째 제네릭 타입에 number를 필수적으로 넣어줘야 합니다.
TQueryKey
항상 string[] 형식으로 전달된다
type QueryKey = string | readonly unknown[];
// queryKey는 string 혹은 array
// 하지만 query function에 전달 방식은 항상 array 형식으로 전달 => string[]
하지만, 명시적으로 배열에 어떤값이 들어가는지 지정해주고 싶을 때 사용한다
const { data } = useQuery<Todo, AxiosError, Todo, [string, number]>({
queryKey: ['todos', id],
queryFn : getTodo
});
useMutation
useMutation 타입은 아래와 같다
export function useMutaion<
TData = unknown, // mutationFn
TError = unknown, // mutationFn
TVariables = void, // mutate
TContext = unknown
>
TData, TError
mutatationFn의 실행 결과 타입이다
const { data } = useMutaion<TodoResponse>({
mutationFn : postTodo,
onSuccess: res => {}
});
// data 타입은 TodoResponse | undefined
// onSuccess callback의 res 타입은 TodoResponse
const { error } = useMutation<TodoResponse, AxiosError>({
mutationFn : postTodo,
onError: err => {}
}
// error 타입은 AxiosError | null
// onError callback의 err 타입은 AxiosError
TVariables
mutateFn의 인자 타입
const { mutate } = useMutation<TodoResponse, AxiosError, number>({
mutationFn :postTodo,
onSuccess: (res, id) => {},
onError: (err, id) => {},
onMutate: id => {},
onSettled: (res, err, id) => {},
});
return <button onClick={() => mutate(5)}>add</button>;
TContext
mutattionFn을 실행하기 전에 수행하는 onMutate의 return 타입
const { mutate } = useMutation<TodoResponse, AxiosError, number, number>({
mutationFn : postTodo,
onSuccess: (res, id, nextId) => {},
onError: (err, id, nextId) => {},
onMutate: id => id + 1,
onSettled: (res, err, id, nextId) => {},
});
// onMutate에서 return으로 주는 number
// onSuccess, onError의 세 번째 인자, onSettled의 네 번째 인자로 받아서 다룰 수 있습니다.
참고자료
https://gusrb3164.github.io/web/2022/01/23/react-query-typescript/