ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [React] React-Query의 개념 및 예제
    FrontEnd/React 2023. 3. 2. 11:27

    React Query는 API 통신과 비동기 데이터 관리에 사용되는 React 라이브러리 입니다.

     

    1. React-Query 이전

    • state에 비동기 데이터를 보관할 경우
      • 다수의 component의 lifecycle에 따라 비동기 데이터가 관리되기 때문에 캐싱 등 최적화를 하기 어려움
      • 다수의 component에서 동일한 API를 호출하거나, 특정 API응답이 다른 API에 영향을 미치는 경우 등에 대응하기 어려움

     

    • Redux를 사용하여 비동기 데이터를 관리할 경우
      • componet의 lifecycle과 관계없이 비동기 데이터를 관리할 수 있어 최적화가 쉬우며 복잡한 사용자 시나리오에도 대응 가능
      • 장황한 Boilerplate 코드로 인해 비동기 Action 처리에 복잡성 증가
      • Redux는 API 통신 및 비동기 상태 관리를 위한 라이브러리가 아니라 Global State Management Library, 즉 전역 상태 관리 라이브러리이기 때문에 API 요청 수행을 위한 규격화된 방식 부재
      • 사용자 경험 향상을 위한 복잡한 시나리오를 수행하는데 많은 개발 리소스 소모

     

     

    2. React-Query란?

    • React Application에서 서버의 상태를 불러오고, 캐싱하며, 지속적으로 동기화하고 업데이트 하는 작업을 도와주는 라이브러리
    • 우리에게 친숙한 Hook을 사용하여 React Component 내부에서 자연스럽게 서버(또는 비동기적인 요청이 필요한 Source)의 데이터를 사용할 수 있는 방법을 제안
    • API 요청을 Query 그리고 Mutation 이라는 두 가지 유형으로 나누어 생각

     

     

    3. Query 요청 개요

    const { status, data, error } = useQuery(
      queryKey, // 이 Query 요청에 대한 응답 데이터를 캐시할 때 사용할 Unique Key (required)
      fetchFn, // 이 Query 요청을 수행하기 위한 Promise를 Return 하는 함수 (required)
      options, // useQuery에서 사용되는 Option 객체 (optional)
    );
    • status
      • isLoading or status === 'loading' - 데이터가 없거나 아직 fetch 중일 때
      • isError or status === 'error' - 데이터를 불러오는 과정에서 error를 호출할 때
      • isSuccess or status === 'success' - 성공적으로 데이터를 불러왔을 때
      • isIdle or status === 'idle' - The query is currently disabled (you'll learn more about this in a bit)... 잘 모르겠음..?

     

    • error
      • isError state에 도달 하면 반환하는 객체

     

    • data
      • isSuccess state에 도달하면 반환하는 객체(데이터)

     

    • isFetching
      • 아직 query가 진행 중이면 isFetchingtrue를 반환

     

     

    4. Query Key

    • Query Key는 string이거나 string이나 nested object로 이루어진 배열로, Query Key를 통해 React Query는 데이터를 캐싱하고 관리한다.
    // string query keys
     useQuery('todos', ...) // queryKey === ['todos']
     
    // array query keys
    useQuery(['todo', 5], ...) // queryKey === ['todo', 5]
    useQuery(['todo', 5, { preview: true }], ...) // queryKey === ['todo', 5, { preview: true }]
    useQuery(['todos', { type: 'done' }], ...) // queryKey === ['todos', { type: 'done' }]
    
    // array key에서 순서가 바뀌면 다른 키
    // ex) 같은 키
    useQuery(['todos', { status, page }], ...)
    useQuery(['todos', { page, status }], ...)
    // ex) 다른 키
    useQuery(['todos', status, page], ...)
    useQuery(['todos', page, status], ...)
    
    // variable이 바뀔 경우에 query를 호출 하고 싶으면 query key에 variable을 담는다. (변수 의존)
     function Todos({ todoId }) {
       const result = useQuery(['todos', todoId], () => fetchTodoById(todoId))
     }

     

     

    5. Query Function

    promise를 반환하는 fuction으로 비동기 요청으로 받은 데이터나 에러를 반환한다.

    // 다음과 같은 방법 모두 사용 가능하다.
    useQuery(['todos'], fetchAllTodos)
    useQuery(['todos', todoId], () => fetchTodoById(todoId))
    useQuery(['todos', todoId], async () => {
       const data = await fetchTodoById(todoId)
       return data
    })
    useQuery(['todos', todoId], ({ queryKey }) => fetchTodoById(queryKey[1]))

     

     

    6. useQueries

    useQuery의 호출 수가 render마다 바뀌는 경우, hook rule을 위반하기 때문에 수동으로 useQuery를 사용할 수 없다. 이때 useQueries를 사용하여 동적으로 query를 호출한다.

     function App({ users }) {
       const userQueries = useQueries(
         users.map(user => {
           return {
             queryKey: ['user', user.id],
             queryFn: () => fetchUserById(user.id),
           }
         })
       )
     }

    React.Suspense모드를 사용할 때도 suspense = true를 적용하여 로딩 상태 처리를 useQuery에서 처리하지 않도록 할 수 있다.

Designed by Tistory.