React-Query는 클라이언트에 대한 서버 값 가져오기, 캐싱, 값 업데이트 및 오류 처리와 같은 비동기 프로세스를 보다 편리하게 만드는 데 사용됩니다.
왜 사용
전)
서버에서 값을 검색하거나 업데이트하는 로직은 비즈니스에서 개발되는 경우가 많습니다. 따라서 스토리지는 클라이언트 상태를 유지해야 하며 어느 시점에서 클라이언트 데이터와 서버 데이터가 스토리지에 공존할 수 있습니다. 그리고 데이터가 서로 상호 작용하면서 서버 데이터도 클라이언트 데이터도 아닌 끔찍한 하이브리드를 생성합니다.
따라서 React-Query를 사용하면 서버와 클라이언트 데이터가 분리됩니다. 이 개념에 동의하지 않더라도 다음과 같은 이점이 보이면 사용을 고려하십시오.
응답 쿼리의 이점
● 캐싱
● 가져온 데이터에 대해 업데이트를 수행하면 GET이 자동으로 다시 실행됩니다.
예) 게시판 메시지를 불러오면 자동으로 게시판 글이 생성되고 게시판 메시지 가져오기 API가 실행됩니다.
● 데이터가 오래된 것으로 판단되면 다시 Get(invalidateQueries)하십시오.
● 동일한 데이터를 여러 번 요청하는 경우 한 번만 요청됩니다. (중복 통화 시간은 요청 시 조정 가능)
● 무한 스크롤(무한 쿼리)
● 비동기 프로세스는 선언적으로 관리할 수 있습니다.
● 사용하는 구조는 리액션 훅과 유사합니다.
사용
먼저 반응 프로젝트를 만듭니다.
npx create-react-app my-app
cd my-app
yarn install react-query
yarn install && yarn start
먼저 React의 가장 기본적인 지점에서 React-Query를 사용하도록 선택합니다.
//src/index.js
import React from "react";
import ReactDOM from "react-dom";
import App from "./App";
import {QueryClient, QueryClientProvider} from "react-query";
import {ReactQueryDevtools} from "react-query/devtools";
const queryClient = new QueryClient();
ReactDOM.render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
{/* devtools */}
<ReactQueryDevtools initialIsOpen={true}/>
<App />
<QueryClientProvider>
</React.StrictMode>,
document.getElementById("root")
);
API
사용 중인 API를 파악한 후 예제를 살펴보겠습니다.
useQuery
● 데이터 조회를 위한 API 입니다. useMutation을 게시하고 업데이트합니다.
● 첫 번째 매개변수로 고유키를 입력하고 두 번째 매개변수로 비동기 함수(API 호출 함수)를 입력한다.
두 번째 매개변수는 약속을 포함해야 합니다.
● 첫 번째 파라미터로 설정된 고유키는 해당 키를 이용하여 다른 컴포넌트에서 불러올 수 있습니다.
고유 키는 문자열과 배열을 받습니다. 배열로 전달하면 값 0은 문자열 값으로 다른 컴포넌트에서 호출할 값을 입력하고, 두 번째 값을 입력하면 해당 값을 쿼리 함수 내에서 매개변수로 전달한다.
● 반환 값은 API 성공 또는 실패와 API 반환 값을 포함하는 객체입니다.
● useQuery는 비동기적으로 작동합니다. 즉, 구성 요소에 여러 useQuery가 있는 경우 하나의 useQuery가 완료된 후 하나의 useQuery가 실행되는 대신 두 개의 useQuery가 동시에 실행됩니다. 비동기 쿼리가 여러 개인 경우 아래 설명과 같이 useQuery 대신 useQueries를 사용하는 것이 좋습니다.
● 활성화되면 useQuery를 동기적으로 사용할 수 있습니다.
예
const Todos = () => {
const {isLoading, isError, data, error} = useQuery{"todos", fetchTodoList, {
refetchOnWindowFocus: false, //react-query 는 사용하는 윈도우가 다른 곳을 갔다가 다시 화면으로 돌아오면 이 함수를 재실행한다. 그 재실행 여부 옵션이다.
retry: 0, //실패시 재호출을 몇 번 할지
onSuccess: data => {
//성공시 호출
console.log(data);
},
onError: e => {
//실패시 호출 (401, 404와 같은 error가 아니라, 정밀 api 호출이 실패한 경우에만 호출된다.
//강제로 에러를 발생시키려면 api단에서 throw Error를 날린다.
console.log(e.message);
}
});
if (isLoading) {
return <span>Error: {error.message}</span>;
}
return (
<ul>
{data.map(todo => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
);
};
● isLoading 및 isSuccess 대신 상태를 즉시 처리할 수 있습니다.
function Todos() {
const {status, data, error} = useQuery("todos", fetchTodoList);
if(status==="loading") {
return <span>Loading...</span>
}
if(status==="error") {
return <span>Error: {error.message></span>;
}
return (
<ul>
{data.map(todo => (
<li key={todo.id}>{todo.title}</li>
))}
</ul>
);
}
useQuery를 동기식으로 실행
● 위에서 언급한 것처럼 enabled 옵션을 사용하면 useQuery를 동기적으로 사용할 수 있다.
● useQuery의 세 번째 인자로 옵션 값을 입력하고 옵션의 enable에 값을 입력하면 그 값이 true일 때 useQuery를 실행한다. 이를 통해 함수를 동기식으로 실행할 수 있습니다.
const {data: todoList, error, isFetching} = useQuery("todos", fetchTodoList);
const {data: nextTodo, error, isFetching} = useQuery(
"nextTodos",
fetchNextTodoList,
{
enabled: !!todoList //true가 되면 fetchNextTodoList를 실행한다.
}
);
useQueris
● 여러 useQuery가 비동기적으로 실행되는 경우 다양한 문제가 발생한다.
consrt usersQuery = useQuery("users", fetchUsers);
const teamsQuery = useQuery("teams", fetchTeams);
const projectsQuery - useQuery("projects", fetchProjects);
//세 함수 모두 비동기로 실행하는데, 세 변수를 개발자는 다 기억해야 하고 세 변수에 대한 로딩, 성공, 실패처리를 모두 해야한다.
● 이 시점에서 useQuery는 useQueries인 promise.all과 같이 하나로 결합될 수 있습니다. Promise.all과 마찬가지로 각 쿼리의 상태 값은 배열의 개체로 입력됩니다.
//아래 예시는 롤 룬과, 스펠을 받아오는 예시이다.
const result = useQueries((
{
queryKey: ("getRune", riot.version),
queryFn: () => api.getRunInfo(riot.version)
},
{
queryKey: ("getSpell", riot.version),
queryFn: () => api.getSpellInfo(riot.version)
}
));
useEffect(() => {
console.log(result); //({rune 정보, defa: (), isSuccess: true ...}, {spell 정보, data: (), isSuccess: true ...})
const loadingFinishAll = result.some(result => result.isLoading);
console.log(loadingFinishAll); //loadingFinishAll이 false이면 최종 완료
}, (result));
#고유키 사용
● 유니크 키를 배열에 넣으면 쿼리 함수 내에서 변수로 사용할 수 있다고 위에서 언급했다. 다음과 같이 사용하십시오. **매개변수 참고**
원천
![[Javascript] 자바스크립트 [Javascript] 자바스크립트](https://high.pageof.kr/wp-content/plugins/contextual-related-posts/default.png)