자바스크립트 - React.js

[ReactQuery] useMutation과 useQuery에서 TypeScript 적용하기

Lv1_junior_dev 2023. 11. 7. 20:26

❗ useMutation에 TypeScript 적용

export function useMutation<
  TData = unknown,
  TError = unknown,
  TVariables = void,
  TContext = unknown
>

 

✔ TData: Mutate 함수가 반환하는 데이터의 타입)

const { data } = useMutation<MyData>(/* mutateFn */);

 

✔TError: Mutate 함수 실행 중 발생할 수 있는 오류의 타입)

const { error } = useMutation(/* mutateFn */, { onError: (err) => console.error(err) });

 

✔TVariables: Mutate 함수에 전달되는 변수의 타입

const { mutate } = useMutation<MyData, MyError, MyVariables>(/* mutateFn */);

 

TContext: 옵션으로 제공되는 컨텍스트의 타입

const { mutate } = useMutation(/* mutateFn */, { context: { /* 컨텍스트 데이터 */ } });

 

 예시

 

이것들을 복합적으로 사용한 예시이다

import { useMutation } from '@tanstack/react-query';

interface UserData {
  id: number;
  name: string;
  email: string;
}

const updateUser = async (updatedData: UserData): Promise<UserData> => {
  const response = await fetch(`/api/users/${updatedData.id}`, {
    method: 'PUT',
    headers: {
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(updatedData),
  });

  if (!response.ok) {
    throw new Error('Failed to update user data');
  }

  return response.json();
};

const { mutate, data, error } = useMutation<UserData, Error, UserData>(
  updateUser
);

// 사용 예시
mutate({ id: 1, name: 'Updated Name', email: 'updated@email.com' });

if (error) {
  // 에러 처리
} else if (data) {
  // 데이터 사용
}

 

위 예시에서

 

TData: useMutation 훅에서 반환된 data 변수는 updateUser 함수가 반환하는 데이터의 타입인 UserData로 설정된다.

TError: error 변수는 updateUser 함수가 에러를 던질 수 있으므로, 에러의 타입으로 Error를 사용했다.

TVariables: mutate 함수를 호출할 때 전달되는 변수의 타입은 UserData로 설정되었다. 이는 updateUser 함수가 사용자 데이터를 매개변수로 받기 때문이다.

TContext: 해당 예제에서는 추가적인 컨텍스트를 사용하지 않았으므로 unknown으로 설정되어 있다.

 

<
TData : UserData
TError : Error
TVariables : UserData
TContext : unknown

>

 


❗ useQuery에 TypeScript 적용

export function useQuery<
  TQueryFnData = unknown,
  TError = unknown,
  TData = TQueryFnData,
  TQueryKey extends QueryKey = QueryKey
>

 

✔ TQueryFnData: 쿼리 함수(queryFn)가 반환하는 데이터의 타입

const { data } = useQuery<MyData>(/* queryKey */, /* queryFn */);

 

  TError: 쿼리 실행 중 발생할 수 있는 오류의 타입

const { error } = useQuery(/* queryKey */, /* queryFn */, { retry: false });

 

  TData: 쿼리에서 반환되는 실제 데이터의 타입

const { data } = useQuery<MyData>(/* queryKey */, /* queryFn */);

 

  TQueryKey: 쿼리의 키를 나타내는 타입

const { data } = useQuery(/* ['example', 1] */, /* queryFn */);

 

 

✔ 예시

 

이것들을 복합적으로 사용한 예시이다

interface UserData {
  id: number;
  name: string;
  email: string;
}

const fetchUserData = async (userId: number): Promise<UserData> => {
  const response = await fetch(`/api/users/${userId}`);
  if (!response.ok) {
    throw new Error('Failed to fetch user data');
  }
  return response.json();
};

const { data, error } = useQuery<UserData, Error, UserData>(['user', 1], () => fetchUserData(1));

if (error) {
  // Handle error
} else if (data) {
  // Use data
}

 

 

위 예시에서

TQueryFnData: 쿼리 함수(queryFn)가 반환하는 데이터의 타입이다. 이 예제에서는 fetchUserData 함수가 Promise<UserData>를 반환하므로 UserData 타입이 TQueryFnData에 해당한다.

TError: 쿼리 실행 중 발생할 수 있는 오류의 타입이다. 여기서는 일반적으로 네트워크 오류 등이 발생할 때 사용자에게 보여줄 에러의 타입으로 Error를 사용했다.

TData: 쿼리에서 실제로 반환되는 데이터의 타입이다. 이 예제에서는 useQuery에서 data 변수를 통해 받는 데이터의 타입으로 UserData를 사용했다.

TQueryKey: 쿼리의 키를 나타내는 타입이다. 여기서는 ['user', 1]와 같이 배열 형태로 키를 정의했으므로 QueryKey 타입으로 [string, number]와 같이 생각할 수 있습니다.


<
TQueryFnData: UserData
TError: Error
TData: UserData
TQueryKey: ['user', 1]

>