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;
// 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에 대한 대응을 간편하게 할 수 있다.
반환된 결과는 캐싱이 되어있기 때문에 차후의 동일한 요청에 대해서는 서버에서 값을 받아오지않고 캐싱된 값을 사용하여 빠르게 응답한다.
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 권장.
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반환.