[ReactQuery] queryClient

김호중·2024년 7월 19일
0

React

목록 보기
10/15

QueryClient 공식문서

cache와의 인터랙션을 위해 사용된다.

cache를 전역적으로 사용하기 위해 처음 해야할 일은 App 컴포넌트에 queryClient 인스턴스를 생성하고 Provider에 넣어주는 것이다.

import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
...

const queryClient = new QueryClient();

function Root() {
  return (
        <QueryClientProvider client={queryClient}>
            <App />
        </QueryClientProvider>
  );
}

이로써 useQueryClient를 통해 queryClient에 접근할 수 있게 된다.


이는 어떤 구조로 이루어져 있는지 간단하게 살펴보자.

즉 queryCache, mutationCache를 담고있다. 아래는 실제 QueryClient 구조체이다.
(잘려진 더 아래에는 당연하게도 수많은 메서드가 존재한다.)
각 메서드 종류와 역할은 공식문서를 참고한다.

export declare class QueryClient {
    private queryCache;
    private mutationCache;
    private defaultOptions;
    private queryDefaults;
    private mutationDefaults;
    private unsubscribeFocus?;
    private unsubscribeOnline?;
    constructor(config?: QueryClientConfig);
    mount(): void;
    unmount(): void;
  ...
}

QueryCache(mutationCache와는 조금 다름..)

queies가 있는 것을 볼 수 있다. 이를 구성하는 각 Query는 hash를 갖고있으며 이는 querykey를 stringify한 값이다. (queryKey에 유니크한 값을 할당해야하는 이유)

export declare class QueryCache extends Subscribable<QueryCacheListener> {
    config: QueryCacheConfig;
    private queries;
    private queriesMap;
    constructor(config?: QueryCacheConfig);
    build<TQueryFnData, TError, TData, TQueryKey extends QueryKey>(client: QueryClient, options: QueryOptions<TQueryFnData, TError, TData, TQueryKey>, state?: QueryState<TData, TError>): Query<TQueryFnData, TError, TData, TQueryKey>;
    add(query: Query<any, any, any, any>): void;
    remove(query: Query<any, any, any, any>): void;
    clear(): void;
    get<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueyKey extends QueryKey = QueryKey>(queryHash: string): Query<TQueryFnData, TError, TData, TQueyKey> | undefined;
    getAll(): Query[];
    find<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData>(arg1: QueryKey, arg2?: QueryFilters): Query<TQueryFnData, TError, TData> | undefined;
    findAll(queryKey?: QueryKey, filters?: QueryFilters): Query[];
    findAll(filters?: QueryFilters): Query[];
    findAll(arg1?: QueryKey | QueryFilters, arg2?: QueryFilters): Query[];
    notify(event: QueryCacheNotifyEvent): void;
    onFocus(): void;
    onOnline(): void;
}

Query

위에 설명에 이어 각 유니크한 Query는 아래와같이 구성되어있다.

export declare class Query<TQueryFnData = unknown, TError = unknown, TData = TQueryFnData, TQueryKey extends QueryKey = QueryKey> {
    queryKey: TQueryKey;
    queryHash: string;
    options: QueryOptions<TQueryFnData, TError, TData, TQueryKey>;
    initialState: QueryState<TData, TError>;
    revertState?: QueryState<TData, TError>;
    state: QueryState<TData, TError>;
    cacheTime: number;
    meta: QueryMeta | undefined;
    private cache;
    private promise?;
    private gcTimeout?;
    private retryer?;
    private observers;
  ...
}

이는 observers를 갖고있으며, 해당 Query가 위치한 cache(상위의 QueryCache) 정보도 갖고있다.

이를 생각해보면 아래와 같은 결론이 나게 된다. (useQuery를 호출할 시)

Query ↔️ Ovserver ↔️ Component


ref.

profile
개발의 흔적을 남기고 쌓아가기 위한 일기장

0개의 댓글