2. useQuery의 활용

우동이·2022년 4월 21일
3

React-Query

목록 보기
2/3
post-thumbnail
post-custom-banner

1. useQuery의 동기처리

  • useQuery는 기본적으로 비동기로 작동합니다.
  • enabled 옵션 활용하여 동기처리를 진행할 수 있습니다.
import React from "react";
import axios from "axios";
import { useQuery } from "react-query";

import "./App.css";

function App() {
  const fetchList_1 = () => {
    return axios(`https://jsonplaceholder.typicode.com/posts/1`);
  };
  const fetchList_2 = () => {
    return axios(`https://jsonplaceholder.typicode.com/posts/5`);
  };

  const { data: data_1 } = useQuery("key_1", fetchList_1, {
    refetchOnWindowFocus: false,
    retry: 0,
  });

  const { data: data_2 } = useQuery("key_2", fetchList_2, {
    refetchOnWindowFocus: false,
    retry: 0,
    // true일 경우 해당 Query 실행
    enabled: !!data_1,
  });
}

export default App;

2. useQueries의 활용

  • promise.all과 동일하게 useQuery를 하나로 묶을 수 있습니다.
  • 하나의 배열에 각 쿼리에 대한 상태 값이 객체로 들어갑니다.
import React from "react";
import axios from "axios";
import { useQuery, useQueries } from "react-query";

import "./App.css";

function App() {
  const fetchList_1 = () => {
    return axios(`https://jsonplaceholder.typicode.com/posts/1`);
  };
  const fetchList_2 = () => {
    return axios(`https://jsonplaceholder.typicode.com/posts/5`);
  };

  // result: [{1번 쿼리 결과}, {2번 쿼리 결과}]
  const result = useQueries([
    {
      queryKey: "key",
      queryFn: fetchList_1,
    },
    {
      queryKey: "key_2",
      queryFn: fetchList_2,
    },
  ]);

  const lodaing = result.some((result) => result.isLoading);
  
  // lodaing이 false이면 모든 query 요청이 완료된 것!
  console.log(finish);

  return <div>hello</div>;
}

export default App;

3. Unique Key 활용

  • Unique key를 배열에 넣으면 query함수 내부에서 변수로 사용 가능합니다.
import React from "react";
import axios from "axios";
import { useQuery, useQueries } from "react-query";

import "./App.css";

function App() {
  const fetchList_1 = () => {
    return axios(`https://jsonplaceholder.typicode.com/posts/1`);
  };
  const fetchList_2 = () => {
    return axios(`https://jsonplaceholder.typicode.com/posts/5`);
  };

  const result = useQueries([
    {
      queryKey: ["key", "value"],
      queryFn: (params) => {
        //  {queryKey: ['key', 'value']}
        console.log(params);
      },
    },
  ]);

  return <div>hello</div>;
}

export default App;
  • 키를 동적으로 관리할 수 있습니다.
const uniqueKey = {
  key: ["key"],
  keyByValue: (value) => ["key", value],
};

useQuery(uniqueKey.key, fetch);
useQuery(uniqueKey.keyByValue('value'), () => fetch(value));

4. QueryCache

  • 쿼리에 대한 성공 / 실패 전처리를 진행할 수 있습니다.
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import { QueryClient, QueryClientProvider, QueryCache } from "react-query";
import { ReactQueryDevtools } from "react-query/devtools";

const queryClient = new QueryClient({
  queryCache: new QueryCache({
    onError: (error, query) => {
      if (query.state.data !== undefined) {
        console.log(`에러 발생: ${error.message}`);
      }
    },
    onSuccess: (data) => {
      console.log(data);
    },
  }),
});

ReactDOM.render(
  <QueryClientProvider client={queryClient}>
    {/* devtools */}
    <ReactQueryDevtools initialIsOpen={true} />
    <App />
  </QueryClientProvider>,
  document.getElementById("root")
);

5. 커스텀 훅 활용 + TypeScript

  • 커스텀 훅을 만들어서 공통 모듈로 사용할 수 있습니다.
    • 파라미터로 옵션을 전달 받습니다.
import { AxiosError } from "axios";
import { useQuery, UseQueryOptions, UseQueryResult } from "react-query";

export default function useFetchQuery(
  options?: UseQueryOptions<valueType[], AxiosError>
): UseQueryResult<valueType[], AxiosError> {
  return useQuery(key, fetch, options);
}

// 사용하기
import useFetchQuery from 'hooks/useTodosQuery';

const { status, isLoading, isSuccess, isError, data, error } = useFetchQuery(); 

6. Default Option 설정 가능

  • 최상단의 QueryClient에서 Default Optoin을 설정할 수 있습니다.
const queryClient = new QueryClient({
  defaultOptions: {
    queries: {
      // refetching 막기
      refetchOnMount: false,
      refetchOnReconnect: false,
      refetchOnWindowFocus: false,
    }
  }
});
profile
아직 나는 취해있을 수 없다...
post-custom-banner

0개의 댓글