react
시리즈에서 API 서버로 HTTP 요청을 보내기 위해 react-query
를 사용하는 방법을 포스팅 했었는데, apollo
를 사용하여 서버와 클라이언트를 연동할 때에도 비슷한 훅을 사용할 수 있다.
이 훅들은 react-query
라이브러리가 아닌 @apollo/client
라이브러리에 내장되어있는 훅으로 모양은 같아도 사용법은 살짝 다르다.
react-query
와 마찬가지로 useQuery
훅은 HTTP GET 요청을 전송할 때 사용된다.
import { gql, useQuery } from '@apollo/client';
const GET_DOGS = gql`
query GetDogs {
dogs {
id
breed
}
}
`;
function Dogs({ onDogSelected }) {
const { loading, error, data, refetch } = useQuery(GET_DOGS, {
variables: { breed },
});
if (loading) return 'Loading...';
if (error) return `Error! ${error.message}`;
return (
<select name='dog' onChange={onDogSelected}>
{data.dogs.map((dog) => (
<option key={dog.id} value={dog.breed}>
{dog.breed}
</option>
))}
<button onClick={() => refetch()}>
Refetch new breed!
</button>
</select>
);
}
export default Dogs
react-query
에서는 useQuery
훅의 option으로 전달하는 enabled 속성을 통해 lazy fetching이 가능했는데 apollo-client
에서는 아예 useLazyQuery
훅이 따로 존재한다.
import React from 'react';
import { useLazyQuery } from '@apollo/client';
const GET_DOG_PHOTO = gql`
query Dog($breed: String!) {
dog(breed: $breed) {
id
displayImage
}
}
`;
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를 fetching 시키는 함수이다.
마지막으로 HTTP POST, PUT, PATCH, DELETE 등의 요청을 담당하는 useMutation
훅이다.
import { gql, useMutation } from '@apollo/client';
const ADD_TODO = gql`
mutation AddTodo($type: String!) {
addTodo(type: $type) {
id
type
}
}
`;
function AddTodo() {
let input;
const [addTodo, { data, loading, error }] = useMutation(ADD_TODO);
if (loading) return 'Submitting...';
if (error) return `Submission error! ${error.message}`;
return (
<div>
<form
onSubmit={e => {
e.preventDefault();
addTodo({ variables: { type: input.value } });
input.value = '';
}}
>
<input
ref={node => {
input = node;
}}
/>
<button type="submit">Add Todo</button>
</form>
</div>
);
}