[React][TypeScript] 내가 경험한 react-query에 대한 정리
안녕하세요! 이번 주면 약 두 달간 진행된 '있어요?' 프로젝트가 끝나네요 ㅎㅎ 차차 또 프로젝트 하면서 다뤘던 것에 대해서 포스팅해보겠습니다악!!
최근 며칠 간 댓글 기능이 있는 상세페이지 작업을 했는데 작업을 하며 react-query를 다뤄보게 되었습니다. 댓글 등록, 수정, 삭제가 제 파트였는데 리액트 쿼리를 다루게 된 배경은 이렇습니다.
새로운 댓글을 등록, 수정, 삭제하면 서버에서 fetch된 댓글 리스트를 다시 불러와줘야 되는데 ..?
라는 문제점에 봉착했었습니다. 처음에는 단순하게 생각해서 그러면 또 서버에서 댓글 리스트를 뿌려주는 api를 호출해주면 되지! 라고 생각을 하였습니다. 근데 댓글을 작성하고 다시 댓글리스트를 호출하는 로직을 작성하게 되면 받아온 데이터를 또 state에 넘겨주는 작업이 필요한데 그러면 코드가 굉장히 복잡해지는 단점이 있었습니다.
그래서 알아보니 데이터를 캐싱해주는 react-query라는 좋은 기능이 있었습니다. 캐싱된 데이터로 api를 불러주는 작업을 줄여주는 것이었죠!
✅ React-Query의 원리
React-Query의 원리는 이렇습니다.
key에다가 api 정보를 기억한다 => key에 담긴 api로 댓글 리스트를 뿌려준다 => 새로운 댓글들이 생긴다 => 키 값의 기존 value를 무효화시키고 key로 댓글 리스트를 다시 받아온다.
✅ React-Query 쓰는 법
1. key에다가 api를 지정해주고, data를 받아옵니다.
const { 받아올 data } = useQuery([키], 함수)
만약 댓글 리스트를 불러와주는 api를 키에 저장하고 싶다면 이렇게 쓰면 됩니다.
const { data } = useQuery(["comments", postId], ()=>commentList(postId))
- commentList라는 api는 댓글 리스트를 불러와주는 애고, 얘를 키에 저장할 건데 comments라는 이름의 키이며 api에는 postId가 필요해서 값을 넘겨줍니다.
- 키 [“comments”, postId] 에서 comments는 분류목적의 이름을 적어준 것이고, postId가 api에 넘겨주는 실질적인 값입니다.
- data에는 현재 댓글들의 리스트가 남겨있습니다.
2. useMutation()으로 데이터 변경 작업을 요청합니다.
const { mutate } = useMutaion(mutaionFn, options)
- mutationFn: 데이터 변경을 위한 api 호출
- options: 여러가지가 있는데, 대표적인 onSuccess는 mutaion이 성공하고 결과를 전달할 때 사용합니다.
새로운 댓글을 쓰고 난 뒤 등록버튼을 누르면 새로운 댓글 리스트를 불러와주는 작업을 예로 들어보겠습니다.
const onSuccess = () => {
alert("댓글이 등록되었습니다.");
queryClient.invalidateQueries(['comments', postId]); // 새로 fetch된 데이터로 갈아끼워주는 역할을 수행해줍니다.
}
const { mutate } = useMutation( // mutate()로 호출 시 데이터 변경이 이뤄집니다.
()=>writeComment(postId, content),
{
onSuccess: onSuccess; // 댓글쓰기가 성공할 경우, onSuccess 함수를 불러줍니다.
}
)
mutate(); // 데이터 변경이 필요한 곳에서 호출해줍니다.
결과적으로 새로운 댓글을 쓰게 되면 새로운 댓글이 기존 댓글 리스트에 올라가게 되고, 리스트를 받아와주는 Key를 불러와서 새로 fetch된 데이터로 갈아끼워줍니다.
✅ 결론
댓글이 추가되는 대로 계속 최신 댓글 리스트를 반환받아야 함
근데 댓글 리스트를 최신으로 받으려면 api 호출을 계속 해줘야 함
근데! react-query를 쓰면? 댓글을 반환해주는 api를 key에 저장을 해줄 수가 있음
그래서 새로운 댓글을 받아오고 싶을 때마다 key를 불러와줘서 새로운 데이터로 fetch된 리스트를 불러올 수 있음
key를 불러와주는 곳은 mutate=>success 쪽에서 불러오면 됨.