Javascript/React

[React Query] React Query with Typescript 그리고 custom hooks

  • -
728x90

useQuery

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

TQueryFnData

  1. TQueryFnData는 useQuery로 실행하는 query function의 반환값을 정하는 제네릭 타입이다.

 TError

  1. TError는 query function의 error 형식을 정하는 제네릭 타입이다.

 TData

  1. TData는 data에 담기는 실질적 type을 뜻한다.
  2. useQuery의 select option으로 query function의 데이터를 2차 가공하는 경우에만 사용하는 type이다.
  3. 데이터 속성이 query function이 반환하는 것과 다를 수 있으므로 선택적으로 사용할 수 있고, 사용하지 않는다면 query function이 반환하는대로 기본값이 설정된다.

TQueryKey

  1. queryKey의 타입을 명시적으로 지정해주는 제네릭 타입이다. queryKey가 어떤 형태로 들어가는지 명시적으로 지정해주고 싶다면 이 기능을 사용하면된다.

useMutation

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

TData

  1. TData는 useMutation에 넘겨준 mutationFn의 실행 결과의 타입이다. 이 타입은 onSuccess와 data에서 활용할 수 있다.
const { data } = useMutaion<PostResponse>(newPost, { onSuccess: res => {} });
// data 타입은 TodoResponse | undefined 
// onSuccess callback의 res 타입은 TodoResponse

TError

  1. TError는 useMutation에 넘겨준 mutationFn의 에러 결과 타입이다. 이 타입은 onError와 error에서 활용할 수 있다.
const { error } = useMutation<TodoResponse, AxiosError>(postTodo, { onError: err => {} });

// error 타입은 AxiosError | null
// onError callback의 err 타입은 AxiosError

TContext

  1. TContext는 mutationFn을 실행하기 전에 수행하는 onMutate 콜백 함수의 반환값을 지정하는 타입이다. onMutate의 결과 값을 onSuccess, onError, onSettled에서 활용하려면 이 타입을 지정해서 활용할 수 있다.
const { mutate } = useMutation<TodoResponse, AxiosError, number, number>(postTodo, {
  onSuccess: (res, id, nextId) => {},
  onError: (err, id, nextId) => {},
  onMutate: id => id + 1,
  onSettled: (res, err, id, nextId) => {},
});

/**
	onMutate에서 return으로 주는 number형식의 결과를
	onSuccess, onError의 세 번째 인자, onSettled의 네 번째 인자로 받아서 다룰 수 있습니다.
*/

 

 

 

 

Custom Hooks

react query와 axios를 활용하여 커스텀 훅을 만들어 필요한 시점에 CRUD를 할 수 있도록 만들어봤다.

import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import axios, { AxiosError, AxiosRequestConfig } from "axios";

export interface Post {
  id?: number;
  title: string;
  body: string;
}

const fetchPosts = async () => {
  const axiosConfig: AxiosRequestConfig = {
    method: "get",
    url: "http://localhost:8000/posts",
    headers: {},
  };

  const response = await axios(axiosConfig);

  return response.data;
};

const createPost = async (newPost: Post) => {
  const axiosConfig: AxiosRequestConfig = {
    method: "post",
    url: "http://localhost:8000/posts",
    headers: {},
    data: newPost,
  };
  const response = await axios(axiosConfig);

  return response;
};

const updatePost = async ({ id, data }: { id: number; data: Post }) => {
  const axiosConfig: AxiosRequestConfig = {
    method: "put",
    url: `http://localhost:8000/posts/${id}`,
    headers: {},
    data: data,
  };

  const response = await axios(axiosConfig);

  return response;
};

const delPost = async (id: number) => {
  const axiosConfig: AxiosRequestConfig = {
    method: "delete",
    url: `http://localhost:8000/posts/${id}`,
    headers: {},
  };

  const response = await axios(axiosConfig);

  return response;
};

export const usePosts = () => {
  const queryClient = useQueryClient();

  const posts = useQuery<Post[], AxiosError>(["posts"], fetchPosts);

  const addPost = useMutation(createPost);

  const editPost = useMutation(updatePost);

  const deletePost = useMutation(delPost);

  return { posts, addPost, editPost, deletePost };
};
728x90
300x250
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.