사용자의 웹 서비스 경험에 있어서 사용자가 직접 서버의 데이터를 변경해야하는 경우가 있을 수 있다. 이때 사용하는 훅은 useMutation()
이다. 서버와의 상호작용을 통해 데이터를 변경하거나 업데이트하는 데 사용된다. 이를 통해 비동기적인 데이터 변경 작업을 간편하게 처리할 수 있다. 기본 사용법은 아래와 같다.
// 임의의 todo를 추가하는 예제
const queryClient = useQueryClient();
const { mutate } = useMutation({
mutationKey: ['postTodo'],
mutationFn: postTodo,
onSuccess: () => {
queryClient.invalidateQueries(['getTodos']);
},
});
return (
...
<button onClick={() => {
mutate({
id: Date.now().toString(),
title: 'new Todo!'
})
}}>
추가
</button>
);
useMutation
mutation할 정보를 담은 객체가 인자로 들어간다.
mutationKey
고유한 key
값을 설정한다.
mutationFn
mutation을 시도하는 비동기 API를 넣어준다. 여기서 postTodo
는 axios의 post함수를 이용하여 임의의 데이터를 추가하였다.
export const postTodo = (todo: Todo) => axios.post('/api/todo', { todo }).then(res => res.data);
queryClient.invalidateQueries
queryClient
은 QueryClient
의 인스턴스를 반환한다. 이는 애플리케이션의 다른 컴포넌트에서 TanStack Query 의 기능에 접근할 수 있다. 이후 데이터를 가져오고 업데이트하거나 캐시를 관리할 수 있게 해준다. 이는 싱글톤으로 작동한다.
또한 invalidateQueries()
는 인자로 들어온 key
값의 query를 실행시켜주는 기능을 한다.
mutate
데이터를 변경 / 추가 / 삭제 등을 해야할 기능에 해당 함수를 넣어준다. 인자에는 mutationFn
속성에 넘겨줄 객체를 담아준다.
백그라운드 패칭중에는 isLoading
이 아닌 isFetching
으로 나타낸다. TanStack Query를 사용하면서 다양한 경우에 백그라운드 패칭이 일어날 수 있다. 이러한 백그라운드 패칭을 글로벌하게 전역적으로 확인할 수 있는 useIsFetching()
훅이 있다. 현재 진행 중인 데이터 요청의 수를 추적하고 반환하는 데 사용된다.
import { useIsFetching } from '@tanstack/react-query'
function GlobalLoadingIndicator() {
const isFetching = useIsFetching()
return isFetching ? (
<div>Queries are fetching in the background...</div>
) : null
;
위의 컴포넌트처럼 사용하면 어떤 모든 query가 fetching중일 때, 해당 컴포넌트가 반환된다.
이러한 유틸리티 기능 외에도, 다양한 window focus상태를 커스터마이징할 수 있다.
데이터가 패칭 중임에도, 데이터가 이미 존재하는 것처럼 UI에 보여주는 기능이다.
이 Placeholder 로 띄워지는 데이터는 더미 데이터이며, 캐싱되지 않으며 아래처럼 사용한다.
const result = useQuery({
queryKey: ['todos'],
queryFn: () => fetch('/todos'),
placeholderData: [
{ id: 1, title: 'Loading...', content: 'Please wait while the data is loading.' },
.
.
.
],
});
이러한 더미데이터들은 useMemo()
훅을 사용해 메모이제이션하면 효과적으로 리렌더링할 수 있다.
이와 비슷한 기능으로는 Initial Query가 있다. 차이점은 초기 데이터를 캐싱할 수 있다는 점에 있다.
UI 라이브러리에서 보여주는 Placeholder 와 데이터패칭 라이브러리에서 나타내는 Palceholder 기능은 비슷하지만 개념과 목적은 다르다. UI 라이브러리에서는, 주로 스켈레톤이라고 불리는데 데이터를 받아올 때 로딩 상태를 시각적으로 보여주기 위한 틀의 목적이 뚜렷하며,
데이터패칭 라이브러리에서는 비동기 데이터 요청이 완료되지 않았을 때 임시로 보여주는 더미 데이터 혹은 디폴트 데이터의 목적을 가지고 있다.
이 두 가지 개념은 서로 보완적인 역할을 하며, 사용자 경험을 향상시키고 데이터 패칭 과정에서 사용자에게 유용한 정보를 제공하는 데 도움이 된다. 따라서 개발자는 상황에 맞게 적절하게 이 기능들을 사용하면 된다.