Backend에서 구성한 query와 mutation을 react에서 사용하는 방식은 크게 두 가지이다.
2번은 apollo/react-hook에서 제공하는 custom hook인데, 나는 이 프로젝트에서 hook을 적극적으로 활용할 것을 하나의 주안점으로 삼았기 때문에 전체적인 통합성을 고려해 이 방식으로 api 요청을 하기로 결정했다.
먼저 원하는 데이터를 받아올 graphql query를 작성해야 한다.
src/lib/queries
export const GET_POST_LIST = gql`
query getPostList(
$page : Int,
$recent : Boolean,
$keyword : String,
$liked : Boolean
) {
posts(
page: $page,
recent: $recent,
keyword: $keyword,
liked: $liked
) {
_id
title
content
thumbNail
likes
created_at
updated_at
author {
_id
name
}
comments {
_id
}
}
}
`;
그 다음 useQuery를 통해 요청을 전송한다. 한 컴포넌트 내에 useQuery를 사용하게 되면 그 컴포넌트 전체가 graphql query로부터 지배적인 영향을 받게 된다.
src/components/container/PostListContainer.js
const { loading, error, data } = useQuery(GET_POST_LIST, {
variables : {
...query,
page : page ? parseInt(page) : 1,
}
});
if(loading) return <div>...loading</div>
if(error) {
console.log(error.message)
return (
<div className={"posts-error-message"}>error occured!</div>
)
}
(...)
return(
<div>
<UserMenu history={history}/>
<PostList
onClickPage={handleClickPage}
postList={data.posts}
title={title}
onPostClick={handlePostClick}
page={parseInt(page) || 1}
/>
</div>
)
마찬가지로 원하는 작업을 실행할 graphql mutation을 작성한다.
src/lib/queryies.js
export const CREATE_POST = gql`
mutation createPost(
$title : String!
$content : String!
$thumbNail : String!
$categoryId : Int!
) {
createPost(
title : $title
content : $content
thumbNail : $thumbNail
categoryId: $categoryId
) {
_id
}
}
`;
그리고 useMutation을 이용해 비동기요청을 처리한다.
src/components/container/Editor/EditorContainer.js
const [createPost] = useMutation(CREATE_POST);
(...)
const handleSubmit = async () => {
createPost({ variables : postState })
.then(response => {
alert('게시물 작성이 완료되었습니다.');
history.push(`/post/${response.data.createPost._id}`)
})
.catch(err => {
alert(err.message)
})
};