react-query에서 query
는 다음과 같이 정의된다.
declarative dependency on an asynchronous source of data that is tied to a unique key
값이다.
query는 Promise based method (GET, POST 등)에 사용되는데, 만약 서버의 상태를 바꿀 의향이 있다면 (POST, PUT, DELETE 등) query 대신 mutation을 사용하길 권장한다.
useQuery
useQuery는 query result를 리턴하는 훅이다. 이는 필수적으로 다음 두 인자를 받는다.
queryKey
: unique keyqueryFn
: (data를 resolve하거나 에러를 던지는 Promise)를 리턴하는 함수이때 unique key는 해당 데이터에 대한 fetch, refetch, cache, share하는 데에 사용된다.
useQuery를 사용해 보자.
const result = useQuery('your-query-key', yourFetchFunction);
이때 result
는 query의 status에 대한 매우 중요한 정보들을 가지고 있다.
isLoading
or status === 'loading'
isError
or status === 'error'
isSuccess
or status === 'success'
isIdle
or status === 'idle'
isError
일 경우 error
변수를 활용하여 에러에 접근할 수 있다.
isSuccess
일 경우 data
변수를 활용하여 데이터에 접근할 수 있다.
어느 state든, 어떤 fetch라도 되고 있다면 isFetching
은 true
이다.
일반적으로, query를 이용해 data를 받는 게 목적일 테니까, 아마도 다음 변수들은 필수적이다.
data
isLoading
isError
error
useQuery의 전달인자로[queryKey, queryFn, config]
배열 대신 객체를 넣을 수도 있다
{queryKey: ['todo', 7], queryFn: fetchTodo, ...config}
query key
는 query를 식별해주는 unique한 key이다. 이는 string처럼 간단할 수도 있고, 객체나 배열이 막 섞여 들어가서 복잡하게 되어 있을 수도 있다. serializable
하고 unique
하면 무엇이든 상관없다. 하지만 분명 주의해야 할 점들이 있다:
useQuery('todos', ...)
queryKey === ['todos']
useQuery(['todos', 5], ...)
['todo', {a: 5, b: 6}]
과 ['todo', {b: 6, a: 5}]
는 같게 취급된다.더하여,
query function이 어떤 외부 변수에 의해 결정된다면, 반드시 query key에 포함해 주도록 한다.
useCallback으로 함수 감쌀 때 dependency에 변수 다 추가해주는 거랑 같은 이유이다.
query function
은 promise를 리턴하는 함수면 된다. 이때 이 promise는 항상 data를 resolve하거나 error를 throw해야 한다.