반응형
react query의 mutate로 optimistic update 구현하기!
개발 기간 동안에도 계속 optimistic update로 구현하고 싶었으나 잘 풀리지 않아서 보류하고 있었던 부분이다.
또 며칠 씨름했었는데 이걸 왜 헤맸지 싶을 정도로 간단하게 해결했다........
왜 헤맸지 진짜? 그래도 결국 내가해냄 하는 마음이 들어 뿌듯했다.
기존에 useState를 사용해 수동으로 optimistic update를 구현했는데, react query를 잘 사용하면 그럴 필요가 없었다.
낙관적 업데이트의 개념과 사용방법은 아래의 링크를 참고하기 바란다.
optimistic update의 핵심은 서버의 응답을 기다리지 않고 UI를 변경해주는 것이다.
이 때 변경전 데이터를 저장해두고 만약 오류가 발생했을 때는 저장해둔 변경 전 데이터로 롤백해주는 것이다.
▶️ 방법
useState로 선언했던 부분을 let 변수로 수정해준다. 이후에 값들이 변경돼야하므로 const가 아닌 let으로 선언해준다.
useMutation부분에 onMutate 함수를 추가한다.
onMutate는 mutation이 시작되기 전에 호출되어 mutation의 실행 전 상태를 기록하거나 업데이트하는 데 사용한다.
롤백을 위한 이전 값을 previousProjectLike에 저장해 두고 setQueryData를 통해 상태를 업데이트해준다.
onError 함수에서는 에러가 발생했을 경우 이전 값으로 데이터를 다시 set해준다.
let countLike = projectLike?.like;
let isLike = myProjects?.likedProjects.includes(pid);
const queryClient = useQueryClient();
const { mutate: updateLikeMutate } = useMutation(
() => updateLike(pid, countLike),
{
onMutate: async () => {
await queryClient.cancelQueries(['post', pid]);
const previousProjectLike = queryClient.getQueryData(['post', pid]);
queryClient.setQueryData(['post', pid], () => {
isLike ? (countLike -= 1) : (countLike += 1);
});
return { previousProjectLike };
},
onError: (err, variables, context) => {
queryClient.setQueryData(['post', pid], context?.previousProjectLike);
},
onSettled: () => {
queryClient.invalidateQueries(['post', pid]);
},
},
const { mutate: updateMyProjectMutate } = useMutation(
() => updateMyProject(uid, pid, isLike),
{
onSuccess: () => {
onMutate: async () => {
await queryClient.cancelQueries(['myProjects', uid]);
const previousMyProjects = queryClient.getQueryData([
'myProjects',
uid,
]);
queryClient.setQueryData(['myProjects', uid], () => {
isLike = !isLike;
});
return { previousMyProjects };
},
onError: (err, variables, context) => {
queryClient.setQueryData(
['myProjects', uid],
context?.previousMyProjects,
);
},
onSettled: () => {
queryClient.invalidateQueries(['myProjects', uid]);
queryClient.invalidateQueries(['post', 'mostViewed']);
queryClient.invalidateQueries(['post', 'mostLiked']);
},
);
반응형
'매일 해내는 개발 > Develog' 카테고리의 다른 글
JavaScirpt 테스팅 프레임워크 Jest 기초 (0) | 2023.05.21 |
---|---|
[Develog] 기술 면접 대비 질문과 답 #2 (1) | 2023.03.27 |
[Develog] 링크드리스트로 투두리스트 구현하기.js (0) | 2023.03.21 |
[Develog] 자바스크립트에서 SSR 구현하는 방법 (0) | 2023.03.16 |
[Develog] SSR과 CSR 비교 (0) | 2023.03.15 |
댓글