react query를 사용하는 이유는 여러 가지 편의를 위한 기능 제공도 있지만 내가 react query로 리팩을 한 가장 큰 이유는 캐싱 기능때문이었다. 게시판 특성상 많은 사람이 동시에 이용해야하고 crud 작업이 무지막지하게 실행되는 곳이기에 같은 정보를 여러 번 불러와 서버를 부하시키는 일을 벌리지 않기 위함이 가장 큰 목적이었고, 이 때문에 react-query를 적용시키게 되었다.
기존에는 한 게시글에 대한 상세 정보와 댓글 정보들을 axios를 통해 server로부터 데이터를 불러왔고 해당 페이지가 렌더링될때마다 다시 서버로부터 데이터를 불러오도록 구현되어 있었다. 이 부분은 그렇다쳐도 가장 신경쓰였던 부분은 댓글이었다. 댓글은 가장 하단에 추가되는 방식이라 새로고침이나 재요청없이 내 단에서 추가된 것처럼 보이게 처리가 가능했는데, 대댓글의 경우는 데이터가 냅다 중간에 끼는 형식이었는데, 급하게 구현하다보니 대댓글을 추가할때는 재요청은 물론 새로고침까지 되면서 사용자의 편의를 크게 떨어뜨린다고 생각했다.
아래와 같이 구현을 해놓을 수 있다. 댓글에 적용한 부분인데, usequery대신 usesuspensequery를 사용해서 성공한 결과만을 전달해줘서 반환이 undefined일 때를 생각하지 않아도 되게끔 했다.
function useGetComment({ communityId }: useGetCommentProps) {
const fetchComment = async () => {
const response = await request<null, PostComment[], CommentParam>({
uri: `/어쩌구/${communityId}`,
method: 'get',
params: {
communityId,
},
});
return response.data;
};
const { data: commentData } = useSuspenseQuery({
queryKey: ['community-comment', communityId],
queryFn: fetchComment,
});
return {
commentData,
};
}
data를 사용할 component에서는 import해준 뒤 아래처럼 사용해주면 된다
const { commentData } = useGetComment({
communityId: Number(communityId),
});
그리고 stale한 데이터에 대해서는 invalid처리를 해서 캐싱데이터를 비우도록 할 수 있다.
queryClient.invalidateQueries({
queryKey: ['community-comment', id],
})
이렇게 처리를 함으로써 쿼리를 무효화해 데이터를 새로 가져올 수 있게 했다. 사용자가 댓글을 업데이트했을 때 해당 변경 사항을 실시간으로 반영할 수 있게 되었다.