프론트엔드에서 중요하지만 쉽지 않고 끝이 없는 상태관리!!!
앱이 복잡해질수록 클라이언트의 자체적인 state뿐 아니라 비동기 작업과 관련된 로딩, 에러, 데이터의 state까지 관리하는 게 복잡해지고, 성능과도 관련이 있다.
회사에서 리덕스로만 모든 상태관리를 하다가 api호출과 관련한 코드는 리액트 쿼리로 바꾼 상태였기 때문에, 리액트 쿼리 살펴보기...!(라고 쓰고 거의 번역)
리액트 쿼리는 비동기 작업에서 특히 서버 상태를 관리하고 캐싱하는 데 유용한 기능을 제공한다.
리엑트 쿼리 세팅하기
import { QueryClient, QueryClientProvider, useQuery } from 'react-query'
//App에서 클라이언트 객체 생성해서 공유
const queryClient = new QueryClient()
export default function App() {
return (
<QueryClientProvider client={queryClient}>
<Example />
</QueryClientProvider>
)
}
function Example() {
//useQuery에서 isLoading(로딩 상태), data 등이 담긴 객체를 리턴
const { isLoading, error, data } = useQuery('repoData', () =>
fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
res.json()
)
)
if (isLoading) return 'Loading...'
if (error) return 'An error has occurred: ' + error.message
return (
<div>
<h1>{data.name}</h1>
<p>{data.description}</p>
<strong>👀 {data.subscribers_count}</strong>{' '}
<strong>✨ {data.stargazers_count}</strong>{' '}
<strong>🍴 {data.forks_count}</strong>
</div>
)
}
쿼리를 구독하기 위해 아래 두가지만 포함해서 훅으로 호출(편리!!!!!!!!!)
const result = useQuery('todos', fetchTodoList)
위에서 반환되는 result 객체는 아래 값들을 가진다.
isLoading
or status === 'loading'
: 쿼리 데이터가 없고 현재 페칭중
isError
or status === 'error'
: 에러 상태 -> error 접근 가능
isSuccess
or status === 'success'
: 쿼리 성공, 데이터 가능 -> data 값 접근 가능
isIdle
or status === 'idle'
: 쿼리 현재 장애?
isFetching
: 백그라운드 리페칭 포함, 쿼리가 페칭상태
리액트 쿼리는 쿼리키를 바탕으로 쿼리를 캐싱한다.
쿼리 키는 1. string 2. string이나 객체로 된 배열일 수 있다.
// A list of todos
useQuery('todos', ...) // queryKey === ['todos']
// An individual todo
useQuery(['todo', 5], ...) // queryKey === ['todo', 5]
// A list of todos that are "done"
useQuery(['todos', { type: 'done' }], ...)
// queryKey === ['todos', { type: 'done' }]
객체 안의 키들의 순서는 상관없이 키가 동일하지만, 배열 안의 요소 순서는 지켜져야 한다.
만약, 쿼리 함수가 변수를 받는 경우, 쿼리 키에 포함해야 한다.
function Todos({ todoId }) {
const result = useQuery(['todos', todoId], () => fetchTodoById(todoId))
}
회사에서는
/api - 리소스별로 axios로 api를 호출하는 함수를 모아두고
/hooks - api 함수를 호출하는 useQuery, useMutation로 api함수를 호출하면서 에러처리 등 옵션을 주는 hook을 만들어서 사용하고 있다.