쿼리에 응답

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));

#고유키 사용

● 유니크 키를 배열에 넣으면 쿼리 함수 내에서 변수로 사용할 수 있다고 위에서 언급했다. 다음과 같이 사용하십시오. **매개변수 참고**


원천

React-Query 개념 및 정리 | 추억 대신 기록 (kyounghwan01.github.io)