리액트 쿼리는 종종 React의 missing data-fetching 라이브러리로 설명되지만 보다 기술적으로 React 애플리케이션에서 서버 상태를 가져오기, 캐싱, 동기화 및 업데이트를 쉽게 수행할 수 있게 해주는 리액트 라이브러리.
리액트 컴포넌트에서 데이터를 가져오거나 업데이트하는 명확한 방법이 없어서 보통 React hooks나 범용적인 상태관리 라이브러리를 사용해 앱 전체에 비동기 데이터를 저장하고 제공함. 대부분의 상태 관리 라이브러리는 client state 조작에는 적합하지만 비동기 또는 server state 작업에는 좋지 않음.
우선 상태란 언제든 변경될 수 있는 것으로, 애플리케이션의 상태는 데이터에 대한 제어, 소유 여부에 따라 server state
와 client state
로 분류할 수 있음
local client state, global client state 두 가지로 구분할 수 있음
feching
및 updating
이 가능함앱의 서버 상태의 특성을 파악하면 다음과 같이 많은 문제가 발생함
React Query는 서버 상태를 관리하기 위한 최고의 라이브러리 중 하나! 구성 없이 즉시 사용 가능하고 여러 장점이 있음
https://react-query-v3.tanstack.com/guides/queries
https://react-query-v3.tanstack.com/reference/useQuery#_top
주요 status
isLoading
or status === 'loading'
- 쿼리에 데이터가 없고 현재 데이터를 요청 중isError
or status === 'error'
- 쿼리에서 에러가 발생한 경우error
- 해당 property로 에러 메세지를 확인isSuccess
or status === 'success'
- 쿼리 요청이 성공했고 데이터를 사용할 수 있음data
- 쿼리가 success
상태인 경우 이 속성으로 데이터를 확인할 수 있음isIdle
or status === 'idle'
- 이 쿼리는 현재 비활성화됨. 사용할 수 없을 때isFetching
- 모든 상태에서, 쿼리가 언제든지 가져오는 경우 (background refetching 포함) isFetching
은 항상 true
를 리턴함 import { useQuery } from 'react-query'
function App() {
const info = useQuery('todos', fetchTodoList)
}
boolean 타입으로 체크
function Todos() {
const { isLoading, isError, data, error } = useQuery('todos', fetchTodoList)
if (isLoading) {
return <span>Loading...</span>
}
if (isError) {
return <span>Error: {error.message}</span>
}
// We can assume by this point that `isSuccess === true`
return (
<ul>
{data.map(todo => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
)
}
status
로 한 번에 처리 가능
function Todos() {
const { status, data, error } = useQuery('todos', fetchTodoList)
if (status === 'loading') {
return <span>Loading...</span>
}
if (status === 'error') {
return <span>Error: {error.message}</span>
}
// also status === 'success', but "else" logic works, too
return (
<ul>
{data.map(todo => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
)
}
key의 가장 간단한 형식은 배열이 아니라 개별 문자열임. string query key가 전달되면 해당 문자열이 쿼리 키의 유일한 항목으로 내부적으로 배열로 변환됨. 이 형식은 다음 경우에 유용함
// A list of todos
useQuery('todos', ...) // queryKey === ['todos']
// Something else, whatever!
useQuery('somethingSpecial', ...) // queryKey === ['somethingSpecial']
쿼리에 데이터를 고유하게 설명하기 위해 추가 정보가 필요한 경우 문자열 및 임의의 수의 직렬화 가능한 객체가 있는 배열를 사용하여 해당 데이터를 설명할 수 있음
// An individual todo
useQuery(['todo', 5], ...)
// queryKey === ['todo', 5]
// An individual todo in a "preview" format
useQuery(['todo', 5, { preview: true }], ...)
// queryKey === ['todo', 5, { preview: true }]
// A list of todos that are "done"
useQuery(['todos', { type: 'done' }], ...)
// queryKey === ['todos', { type: 'done' }]
Query Keys are hashed determin
즉, 객체의 키 순서에 관계없이 다음 쿼리는 모두 동일한 것으로 간주됨
useQuery(['todos', { status, page }], ...)
useQuery(['todos', { page, status }], ...)
useQuery(['todos', { page, status, other: undefined }], ...)
그러나 다음 쿼리 키는 같지 않음. 배열 항목 순서 중요
useQuery(['todos', status, page], ...)
useQuery(['todos', page, status], ...)
useQuery(['todos', undefined, page, status], ...)
Query Key는 가져올 데이터를 고유하게 설명하므로 쿼리 함수에 사용하는 모든 변수를 포함해야 함. 파라미터를 사용할 수 있고 파라미터가 unique 한 값이라면 인자로 받아 아래와 같이 사용할 수 있음
function Todos({ todoId }) {
const result = useQuery(['todos', todoId], () => fetchTodoById(todoId))
}
https://react-query-v3.tanstack.com/guides/mutations
데이터를 create/update/delete 하거나 server side-effects를 수행할 때 사용됨. 이를 위해 React Query는 useMutation
hook을 내보냄
다음은 서버에 새로운 todo를 추가하는 예시
function App() {
const mutation = useMutation(newTodo => {
return axios.post('/todos', newTodo)
})
return (
<div>
{mutation.isLoading ? (
'Adding todo...'
) : (
<>
{mutation.isError ? (
<div>An error occurred: {mutation.error.message}</div>
) : null}
{mutation.isSuccess ? <div>Todo added!</div> : null}
<button
onClick={() => {
mutation.mutate({ id: new Date(), title: 'Do Laundry' })
}}
>
Create Todo
</button>
</>
)}
</div>
)
}
mutation은 주어진 순간에 다음 상태 중 하나만 있을 수 있음
isIdle
또는 status === 'idle'
- 돌연변이가 현재 idle 상태이거나 fresh/reset된 상태isLoading
또는 status === 'loading'
- mutation가 현재 실행 중isError
또는 status === 'error'
- mutation에 오류가 발생isSuccess
또는 status === 'success'
- mutation 성공했고 돌연변이 데이터를 사용할 수 있음