Next action:

[React Query] useQuery 동작원리(1)

1. useQuery는 무엇인고 어떻게 사용하는지

function useQuery (
	queryKey: QueryKey,
	queryFn: QueryFunction,
	options?: UseQueryOptions
): UseQueryResult
--------------------------------------------------------------------
--------------------------------------------------------------------
// 1. useQuery 호출
const result = useQuery(['todos'], fetchTodos)

// 2. 내부적으로 Query 인스턴스 생성
const query = new Query({
  queryKey: ['todos'],
  queryFn: fetchTodos,
  ...options
})
// 3. QueryCache에 쿼리 추가
queryClient.getQueryCache().add(query)

core에는 핵심 객체 4개가 아주 중요하다

QueryClient , QueryCache, Query, QueryObserver

// _app.tsx

import { QueryClient } from '@tanstack/query-core';
import { QueryClientProvider } from '@tanstack/react-query';
import type { AppProps } from 'next/app';

export default function App({ Component, pageProps }: AppProps) {
  const queryClient = new QueryClient();

  return (
    <QueryClientProvider client={queryClient}>
      <Component {...pageProps} />
    </QueryClientProvider>
  );
}
  1. QueryClient

  2. QueryCache

    export class QueryCache extends Subscribable<QueryCacheListener>{
    	config: QueryCacheConfig
    	
      private queries: Query<any, any, any, any>[]
      private queriesMap: QueryHashMap
      
      add(query: Query<any, any, any, any>): void {
        if (!this.queriesMap[query.queryHash]) {
          this.queriesMap[query.queryHash] = query
          this.queries.push(query)
          this.notify({
            type: 'added',
            query,
          })
        }
      }
    }
    
  3. Query

  4. QueryObserver

    export class QueryObserver<...> extends Subscribable<QueryObserverListener<TData, TError>> {
      ...
      constructor(
        client: QueryClient,
        options: QueryObserverOptions<...>
      ) {
        super()
    
        this.client = client
        ...
        this.trackedProps = new Set()
        ...
      }
      ...
      protected onSubscribe(): void {
        if (this.listeners.length === 1) {
          this.currentQuery.addObserver(this)
    
          if (shouldFetchOnMount(this.currentQuery, this.options)) {
            this.executeFetch()
          }
          ...
        }
      }
      ...
      private updateQuery(): void {
        const query = this.client.getQueryCache().build(this.client, this.options)
    
        if (query === this.currentQuery) {
          return
        }
    
        this.currentQuery = query
        ...
      }
    }