[GraphQL Apollo-Client]- Fetch Query ( useQuery사용 시 update 방법과 useLazyQuery로 수동 실행 등..)

박영은·2023년 2월 24일
0

Study

목록 보기
8/9

상황에 따라 더 적합한 것으로 사용

Query

  • React Query를 이용해 서버로부터 데이터를 조회해올 때 사용
    cf) useMutation - 데이터 변경작업
...

const res = useQuery(queryKey, queryFn);

const res = useQuery({
    queryKey: queryKey,
    queryFn: queryFn
});

...

👉 queryKey

: useQuery마다 부여되는 고유 Key, 문자열 또는 배열형태로 사용 가능.
: React Query가 query 캐싱을 관리할 수 있도록 도와줌.

// 문자열
const res = useQuery('persons', queryFn);

// 배열 - 1
const res = useQuery(['persons'], queryFn);

// 배열 - 2
const res = useQuery(['persons', 'add Id'], queryFn);

// 배열 - 3
const res = useQuery(['add Id', 'persons'], queryFn);

// 배열 - 4
const res = useQuery(['persons', {type: 'add', name: 'Id'}], queryFn);
...
import axios from 'axios';
import { useQuery } from 'react-query';

const Query = (): JSX.Element => {

    const getPersons1 = () => {
        const res1 = useQuery(['persons'], queryFn1);
    }
    
    const getPersons2 = () => {
        const res2 = useQuery(['persons'], queryFn2);
    }

    return (
        <div>
            {getPersons1()}
            {getPersons2()}
        </div>
    )
}
...
  • res1과 res2가 동일한 queryKey를 사용하여 데이터를 가져오려고 할 때, 일반적인 상황에서는 res1, res2로 두 번 서버에 request전달된다.
    하지만, 위 코드에서는 res1에서 request를 서버에 전달하게 되면 res2에서는 이미 동일한 queryKey에 대한 결괏값이 있기 때문에 추가 요청을 하지 않고 res1의 결과를 그대로 가져와 사용한다.
    = 서버에 1개의 request만 전달
  • queryFn이 다르게 정의되어 있더라도 res2에서는 res1의 결과를 그대로 전달받기 때문에 queryFn1이 처리된 결과를 확인할 수 있다.

👉 queryFn

: query Function으로 promise 처리가 이루어지는 함수.
=> axios를 이용해 서버에 API 요청하는 코드


// ex 1)
const res = useQuery(['persons'], () => axios.get('http://localhost:8080/persons'));

// ex 2)
const res = useQuery({
    queryKey: ['persons'],
    queryFn: () => axios.get('http://localhost:8080/persons')
});



useLazyQuery

...

 import { useLazyQuery } from '@apollo/client';

 function DelayedQuery() {
   const [getDog, { loading, error, data }] = useLazyQuery(GET_DOG_PHOTO);

   if (loading) return <p>Loading ...</p>;
   if (error) return `Error! ${error}`;

   return (
     <div>
       {data?.dog && <img src={data.dog.displayImage} />}
       <button onClick={() => getDog({ variables: { breed: 'bulldog' } })}>
         Click me!
       </button>
     </div>
   );
 }
 
...

🌱 사용자가 버튼을 클릭하는 것과 같은 다른 이벤트에 대한 응답으로 쿼리를 실행 (수동 실행).

  • 구성 요소 렌더링 외에 이벤트에 대한 응답으로 쿼리를 실행하는 데 적합



Query 방식

👉 Polling 방식

...

 const { loading, error, data } = useQuery(GET_DOG_PHOTO, {
     variables: { breed },
     pollInterval: 500,     (0.5초마다 폴링)
 });
    
...

 return (
    <img src={data.dog.displayImage} style={{ height: 100, width: 100 }} />
 );
 
...

🌱 지정된 주기마다 쿼리 실행 = 서버와 실시간에 가까운 동기화 제공 가능

  • 쿼리에 대한 polling을 활성화하려면 pollInterval 옵션을 설정해준다.



👉 Refetching 방식

...

 const { loading, error, data, refetch } = useQuery(GET_DOG_PHOTO, {
    variables: { breed },
  });
    
...

 return (
    <div>
      <img src={data.dog.displayImage} style={{ height: 100, width: 100 }} />
      <button onClick={() => refetch({ breed: 'new_dog_breed' })}>
        Refetch new breed!
      </button>
    </div>
 );
 
...

🌱 polling처럼 주기적 업데이트가 아니라 ! 특정 사용자 액션에 대한 응답으로 쿼리 결과를 refetch 함.

  • 쿼리에 대한 polling을 활성화하려면 pollInterval 옵션을 설정해준다.
  • 화면을 아래로 당겨 새로고침시키는 등, refreshControl과 함께 쓰이기도 함.



👉 fetch policy & nextFetchPolicy세팅

ex) 
...

 const { loading, error, data } = useQuery(GET_DOGS, {
   fetchPolicy: 'network-only', // Used for first execution
   nextFetchPolicy: 'cache-first', // Used for subsequent executions
 });
 
 ...

1. fetch policy : 쿼리가 첫 번째 실행될 때 사용되는 옵션

2. nextFetchPolicy : 쿼리가 이후 캐시 업데이트에서 어떻게 반응할지 정할 때 사용

fetch policies

  • useQuery 훅은 요청한 데이터가 로컬에서 사용가능한지 확인하기 위해 기본적으로 apollo client 캐시를 체크함.

  • 모든 데이터가 로컬에서 사용가능하면 useQuery 훅은 graphQL서버에 쿼리를 날리지 않음.

  • cashe-first : apollo client의 기본 fetch policy

  • cache-only : 서버에 쿼리를 보내지 않고 캐시만 사용. 캐시에 해당 데이터가 없으면 error발생.

  • cache-and-network : 캐시와 graphQL서버 모두에 대해 전체 쿼리를 실행. 서버 쪽 쿼리의 결과가 캐시된 필드를 수정하면 쿼리가 자동으로 업데이트 됨.
    빠른 응답을 제공 = 캐시된 데이터를 서버 데이터와 일관되게 유지해줌.

  • network-only : 캐시를 체크하지 않고 graphQL서버에 대해 전체 쿼리 실행.
    쿼리의 결과는 캐시에 저장된다. 캐시 데이터가 있더라도 사용하지 않음.
    (=캐시된 데이터를 사용할 수 있을 때 거의 즉각적인 응답을 제공할 수 없음)

  • no-cache : 쿼리 결과가 캐시에 저장되지 않는 점을 제외하면 network-only와 유사함.

  • standby : cache-first와 동일한 논리를 사용하지만, 기본 필드 값이 변경될 때 이 쿼리가 자동으로 업데이트되지 않음.
    refetch와 updateQueries를 사용하여 수동 업데이트 할 수 있음.



👉 옵션

ex) variables , onCompleted, onError, skip, pollInterval, context, client, fetchPolicy 등등..

👉 참고 ) 불러오는 기본형태

import { gql, useQuery } from '@apollo/client';

const GET_DOGS = gql`
  query GetDogs {
    dogs {
      id
      breed
    }
  }
`;

Apollo GraphQL Docs
참고
참고

profile
Front-end

0개의 댓글