queryClient
를 사용하여, QueryClientProvider
에 주입함 으로써 데이터를 프로젝트? 전역에서 사용할 수 잇게 된다. ⇒ Context API를 사용하니깐 가능함.[React Query] stale & cache 동작원리
React Query의 구조와 useQuery 실행 흐름 살펴보기 | 카카오엔터테인먼트 FE 기술블로그
QueryCache
asd가 제공하는 build 메서드에서, useQuery로 넘긴 QueryKey를 hash와 하고 이것을 query인스턴스로 반환한다. 만약에 쿼리 hash값이 기존에 있다면, 해당 쿼리를 반환하고, 쿼리 hash값이 없다면? 새로운 쿼리 인스턴스를 만들어 쿼리 Map에 저장후, 쿼리를 반환한다.
export class QueryCache extends Subscribable<> {
private queries: Query<any, any, any, any>[]
private queriesMap: QueryHashMap
constructor(config?: QueryCacheConfig) {}
// option을 받아서, querykey를 hash화해서
build(client, options, state?) {
const queryKey = options.queryKey!
const queryHash = options.queryHash ?? hashQueryKeyByOptions(queryKey, options);
// queryHash를 킷값으로 활용하여 queriesMap에 저장된 Query 인스턴스를 조회해봅니다.
let query = this.get(queryHash)
// 존재하지 않는다면 새로 생성해서 캐시에 등록 후 반환합니다.
if (!query) {
query = new Query({
cache: this,
logger: client.getLogger(),
queryKey,
queryHash,
options: client.defaultQueryOptions(options),
state,
defaultOptions: client.getQueryDefaults(queryKey),
})
this.add(query)
}
// Query 인스턴스가 존재한다면 바로 반환하고
return query
}
add(query) {
if (!this.queriesMap[query.queryHash]) {
this.queriesMap[query.queryHash] = query
this.queries.push(query)
}
}
}
<aside> 💡
</aside>
QueryObserver
를 생성한다.QueryObserver
는 QueryCache
에 있는 Query를 구독한다.<aside> 💡
이 동작은 각각의 리액트 컴포넌트에서 동일한 옵션으로 **useQuery
**훅을 호출한 경우에 중요한 역할을 하게됩니다. **queryKey
**를 식별자로 활용하여 캐시에 동일한 **Query
**가 존재하고 **Query
**가 가진 QueryState
(서버의 데이터)가 유효한 경우 이 값을 재활용하게 됩니다. 이를 통해 중복된 네트워크 요청이 여러번 발생하지 않도록 합니다.
</aside>
컴포넌트와 서버 중간에서 서버의 데이터 관리를 하고, 이는 react query의 내부의 query에 저장된다. 이 query는 필요한 데이터와 매핑된 query-key만 알고 있다면, 프로젝트에 있는 컴포넌트 어디에서나 접근이 가능하다.
이 쿼리를 개발자가 직접 컨트롤 할 수도 있다.
쿼리키 관리를 효과적으로 하기 위해 어떻게 할까?….
<aside>
💡 밑에 배민은 리액트 쿼리
에서 추천하는 쿼리키 라이브러리를 쓰고 있다고 한다.
</aside>