apollo-client useQuery, useLazyQuery 정리

HyosikPark·2020년 12월 21일
2

graphql

목록 보기
7/8

클라이언트 전역 setting

npm install @apollo/client graphql

// components/apollo-client.ts
import { ApolloClient, InMemoryCache } from '@apollo/client';

export const client = new ApolloClient({
    //graphql endpoint와 연결
  uri:  process.env.NODE_ENV !== 'development'
      ? `${process.env.PRO_END_POINT}`
      : `${process.env.DEV_END_POINT}`,
  cache: new InMemoryCache(),
});

// pages/_app.tsx
import Sidebar from '../components/sidebar/Sidebar';
import { ApolloProvider } from '@apollo/client';
import client from '../components/apollo-client';

function MyApp({ Component, pageProps }) {
  return (
    // wrapping 적용은 무조건 _app.tsx파일에서만
    <ApolloProvider client={client}>
      <Component {...pageProps} />
    </ApolloProvider>
  );
}

export default MyApp;

useQuery

// components/sidebar/Sidebar.tsx

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

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

const sidebar = () => {
  const { loading, error, data } = useQuery(GET_DOGS);

  if (loading) return 'Loading...';
  if (error) return 'Error';
  return(
    data.dog.map(e => ...)
  )
}

컴포넌트가 실행될 때 자동으로 useQuery가 실행된다.
useQuery 실행 인자에 gql태그를 넣어 요청하며 apollo-server resolver를 실행한다.
useQuery hook은 resolver에서 반환하는 결과들 중에서 gql태그로 받아올 값을 선택할 수 있다.
resolver가 실행중일 때는 loading은 true상태이다.
resolver에서 error가 발생하면 error, 성공적으로 값을 받아오면 data에 담긴다.
따라서 loading, error, sucess에 대한 대응을 간편하게 할 수 있다.
반환된 결과는 캐싱이 되어있기 때문에 차후의 동일한 요청에 대해서는 서버에서 값을 받아오지않고 캐싱된 값을 사용하여 빠르게 응답한다.

참고할만한 options

variables : {[key:string] : any}

클라이언트 측에서의 어떠한 값을 담아 보내 resolver에서 그 값을 가공하여 반환해야 할 때 사용
위와같은 객체형식을 지켜야한다.

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

const LOGIN = gql`
  mutation login($email: String!, $password: String!) {
    login(loginInput: { email: $email, password: $password }) {
      id
      nickname
      email
      createdAt
      token
    }
  }
`;

const Login = () => {
  const [value, setValue] = useState({
    email: '',
    password: '',
  });
 
  const [login, { data }] = useMutation(LOGIN, {
    variables: value, // variables: {email, password}
  });

pollInterval : number
number밀리세컨드 간격으로 지속적인 쿼리를 보낼 때 사용.
데이터를 계속 업데이트해야 할 경우 사용한다.
startPolling(interval: number) => void, stopPolling() => void 과 함께 사용

const {data, error, loading, startPolling, stopPolling} = useQuery(LOGIN,{
  variables : value,
  pollInterval: 600 // 600ms간격으로 쿼리 요청
})

const onClick = () => {
  stopPolling();
  startPolling(600);
}

refetch
refetch()를 실행할때마다 쿼리 재 요청.

const {data,error, loading, refetch} = useQuery(...)

function () {
  refetch()
}

문제는 refetch나 polling시에는 loading이 동작하지 않는다.
refetch시에도 로딩임을 나타내주고 싶다면

const { data, loading, error, refetch, networkStatus } = useQuery(USERDATA, {
    notifyOnNetworkStatusChange: true,
  });

  if (loading) return <h1>loading</h1>;

  return ()

notifyOnNetworkStatusChange: true로 설정한다.

첫번째 로딩과 refetch를 구분해서 나타내주고 싶다면?

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

  const { data, loading, error, refetch, networkStatus } = useQuery(USERDATA, {
    notifyOnNetworkStatusChange: true,
  });
     // 대소문자 구분 조심
  if (networkStatus === NetworkStatus.refetch) return <h1>refatching</h1>;

  if (loading) return <h1>loading</h1>;

이렇게 설정하면 첫 로딩때는 loading retch할때마다의 로딩은 refetching문구가 나타난다.

errorPolicy: 'all'
옵션의 기본값은 'none'인데 서버에서 응답에러를 발생할 경우 런타임 에러로 간주한다.
이럴경우에 resolver응답을 모두 중지한다.
'all' 설정해줄 경우 런타임 에러로 취급하지 않는다.

fetchPoicy : "cache-first" 기본값
query 실행시 요구하는 데이터가 캐싱된 데이터와 일치하면 캐싱된 데이터를 바로 가져오고 없으면 서버에 요청한다.
"cache-only" 캐싱된 데이터만 가져오고 캐싱된게 없으면 에러
"cache-and-network" 캐시와 서버 둘다 요청을 보내고 캐싱된 데이터를 수정해야 하면 서버에서 가져와 수정한다.
"network-only : 서버에서만 가져오고 데이터를 캐싱한다.
"no-cache" 서버에서 가져오지만 캐싱하지 않는다.
"cache-first"와 같지만 캐싱값에 변화가 생겨도 자동으로 업데이트를 반영하지 않고 refetch해야 반영이된다.

ssr : boolean
서버사이드 렌더링시에 query를 skip한다.

skip : boolean
query를 항상 skip.

onCompleted : (data) => void 쿼리 후 응답이 성공적으로 받아지고나서 실행되는 callback함수. 인자로 resolver에서 반환한 데이터를 받는다. ex) onCompeted(data) {setValue(data)}

onError : (err) => void 쿼리 응답이 실패한경우 에러 처리 콜백함수

partialRefetch : boolean
쿼리 결과가 어떠한 이유로 부분성공적일 때에 다시 refetch를 실행 기본값은 false지만 true 권장.

참고할만한 results

data : 서버에서 받아온 데이터

previousData : 마지막 쿼리 전에 받아왔던 데이터

loading: 데이터를 받아오는 중일 때 true

error: 런타임 에러

variables : 쿼리 호출 시 보냈던 변수 객체

networkStatus : 1 = loading, 2 = setVariables, 3 = fetchMore, 4 = refetch, 6 = poll, 7 = ready, 8 = error
네트워크 상태에 따른 원하는 처리를 해줄 수 있음.

refetch : 쿼리 재 실행

fetchMore : 쿼리 pagination을 가능하게 하는 옵션

startPolling, stopPolling : 콜백함수
pollinterval : number 옵션과 함께 사용
옵션에 pollinterval : number (ms단위)를 설정해두면 어딘가에서 startPolling(number)을 해주면 number간격으로 query가 refetch되며 stopPolling() 시에 중단.
number는 둘다 일치해야함.

updateQuery : 콜백함수

called : boolean
useLazyQuery에 사용되는 결과로써 useLazyQuery가 호출되면 true반환.

0개의 댓글