// root index.js
import { QueryClient, QueryClientProvider } from "react-query";
import { ReactQueryDevtools } from "react-query/devtools";
const queryClient = new QueryClient();
const root = ReactDOM.createRoot(
document.getElementById("root") as HTMLElement
);
root.render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<ReactQueryDevtools initialIsOpen />
<Routes />
</QueryClientProvider>
</React.StrictMode>
);
const result = useQuery({
queryKey,
queryFn,
enabled,
});
import { useQuery } from "react-query";
const Test = () => {
// fetch api 함수
const HandleFetch = (): Promise<any> => {
return fetch("/mock.json", {}); // promise를 반환해야 하기 떄문에 return해준다.
};
// useQuery 사용
const { isLoading, isError, data, error } = useQuery(
["HandleFetch", params1, params2]], // string은 unique Key,
() => HandleFetch() .then((res) => res.json())
.then((res) => setTest(res)),
{
refetchOnWindowFocus: false, // 사용자가 사용하는 윈도우가 다른 곳을 갔다가 다시 화면으로 돌아오면 이 함수를 재실행 하는 지 여부 설정
retry: 0, // 호출 실패 시 재호출 몇번 할지
suspense: true, // suspense 컴포넌트를 사용하여 isLoading을 대체할 수 있다.
useErrorBoundary: true, // useErrorBoundary 컴포넌트를 사용하여 isError를 대체할 수 있다.
// refetchInterval: 3000, // 해당 시간마다 반복하여 호출
onSuccess: () => {
console.log(test); // 성공 시 실행
},
onError() {
console.log(error); // 실패 시 실행 (401, 404 같은 error가 아니라 정말 api 호출이 실패한 경우만 호출)
},
}
);
return (
<ul>
{isLoading && "loading..."}
{isError && "Error!"}
</ul>
);
};
export default Test;
import { useQuery } from "react-query";
import { Suspense } from "react";
import { ErrorBoundary } from "react-error-boundary";
const Test = () => {
const HandleFetch = (): Promise<any> => {
return fetch("/mock.json", {});
};
const { data } = useQuery(
["HandleFetching"],
() =>
HandleFetch()
.then((res) => res.json())
.then((res) => setTest(res)),
{
refetchOnWindowFocus: false,
retry: 0,
suspense: true, // suspense 컴포넌트를 사용하여 isLoading을 대체할 수 있다.
useErrorBoundary: true, // useErrorBoundary 컴포넌트를 사용하여 isError를 대체할 수 있다.
}
);
// 아래와 같이 Suspense, ErrorBoundary 컴포넌트를 사용하며 true가 되면 fallback 컴포넌트가 렌더링 된다.
return (
<ul>
<Suspense fallback={<LoadingPage />}>
<ErrorBoundary fallbackRender={<ErrorPage />}>
<ul>
{data.map((el) => (
<li key={el.id}>{el.name}</li>
))}
</ul>
</ErrorBoundary>
</Suspense>
</ul>
);
};
const {
data,
dataUpdatedAt,
error,
errorUpdatedAt,
failureCount,
isError,
isFetched,
isFetchedAfterMount,
isFetching,
isIdle,
isLoading,
isLoadingError,
isPlaceholderData,
isPreviousData,
isRefetchError,
isRefetching,
isStale,
isSuccess,
refetch,
remove,
status,
} = useQuery(queryKey, queryFn?, {
cacheTime,
enabled,
initialData,
initialDataUpdatedAt
isDataEqual,
keepPreviousData,
meta,
notifyOnChangeProps,
notifyOnChangePropsExclusions,
onError,
onSettled,
onSuccess,
placeholderData,
queryKeyHashFn,
refetchInterval,
refetchIntervalInBackground,
refetchOnMount,
refetchOnReconnect,
refetchOnWindowFocus,
retry,
retryOnMount,
retryDelay,
select,
staleTime,
structuralSharing,
suspense,
useErrorBoundary,
})
useQueries : 여러 개의 비동기를 처리할 경우 사용할 수 있다. promise.all과 마찬가지로 하나의 배열에 각 쿼리에 대한 상태 값이 객체로 들어온다.
proxy로 우회하기 : CORS에러를 피하기 위해 package.json에 "proxy" 값을 설정하여 우회할 수 있다.
// package.json
{
...
"prettier": "^2.6.2",
"sass": "^1.51.0",
"sass-loader": "^12.6.0",
"style-loader": "^3.3.1",
"stylelint": "^14.8.1",
"stylelint-config-recess-order": "^3.0.0",
"stylelint-config-standard-scss": "^3.0.0",
"stylelint-declaration-strict-value": "^1.8.0",
"typescript": "^4.4.2"
},
"proxy": "http://apis.data.go.kr/"
}