리액트 쿼리에 대해서 문서를 통해 알아보자.
기본적으로 리액트에선 데이터를 가져오거나 업데이트해주는 빌트인 기능이 제공되지 않는다. 그래서 일반적으로는 hooks를 사용해 데이터를 가져오거나 업데이트를 거친다.
리액트 쿼리는 기본적으로 이런 기능을 별도의 구성없이도 사용할 수 있는 장점이 있다. 리액트 쿼리는 데이터를 가져오는 것도 가능하지만 아래와 같은 기능도 수행할 수 있다. 그리고 프론트엔드 개발자가 구현해야할 귀찮은 사항들을 간편하게 사용할 수 있게 도와준다.
대표적으로는 다음과 같은 기능을 한다.
기본적으로 useQuery 또는 useInfiniteQuery를 통한 쿼리 인스턴스는 캐시된 데이터를 오래된 것으로 간주한다.
이 동작을 변경하려면 staleTime 옵션을 사용하여 쿼리를 전체적으로 구성하고 쿼리별로 구성할 수 있다. 더 긴 staleTime을 지정하면 쿼리가 데이터를 자주 다시 가져오지 않음을 의미한다.
오래된 쿼리는 다음과 같은 경우 백그라운드에서 자동으로 다시 가져옵니다.
데이터를 get하기 위한 데이터다. useQuery는 보통 비동기로 실행되는데, enabled 속성을 통해 동기적으로 함수를 실행할 수 있다.
이때 unique key는 앱 내부적으로 데이터를 리패치, 캐싱, 공유하기 위해 사용된다.
import { useQuery } from 'react-query'
function App() {
const result = useQuery('todos', fetchTodoList)
}
이때 result에는 결과와 관련된 상태들이 객체로 포함되어 있다.
가져올수있는 형태는 아래와 같다.
만약 위의 목록이 너무 많다면 status
만 가져와서 처리하는 것도 가능하다.
만약 여러개의 useQuery를 사용해야한다면, 이에 대한 로딩, 에러, 성공 처리를 따로해줘야한다.이런 불행을 막기위해 useQueries가 있다.
이때 promise.all
처럼 useQuery를 하나로 묶을 수 있게 된다. promise.all
과 마찬가지로 하나의 배열에 각 쿼리에 대한 상태 값이 객체로 들어옵니다.
데이터를 수정, 업데이트하거나 전송할때 사용된다.
post, update에는 mutation을 사용한다.
사용법은 useQuery와 동일하다.
useMutation을 실제 프로젝트에서 정말 많이 사용했는데, 예를 들어 게시판 기능을 만든다고 생각해보자. 새로운 글을 올렸는데 글 리스트에서 즉시 보이지 않고, 새로고침해야 보이는 상황이라고 해보자.
이때 react-query를 쓰면 간단히 해결 가능하다.
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>
)
}
이때 이제 전송을 보내고 새롭게 데이터를 받으려면 간단한 코드 하나만 추가해주면된다.
앞서서 qurey에 unique key를 달아준것을 기억하고 있다면 더 쉽다. invalidateQuries()에 해당 unique key를 넣어주면 mutation 이후 해당 unique key를 가진 qurey를 재실행하게 된다.
// Invalidate every query with a key that starts with `todos`
queryClient.invalidateQueries('todos')
공감하며 읽었습니다. 좋은 글 감사드립니다.