낙관적 업데이트 적용

차차·2023년 2월 8일
0
post-thumbnail

이번에는 사용자 경험을 더 좋게 하기 위해 낙관적 업데이트를 적용해보았다.

낙관적 업데이트 (Optimistic Update)

낙관적 업데이트란 클라이언트에서 먼저 UI를 업데이트 시켜주고 서버에 요청을 하는 것이다.

기존 방식은 서버 요청 → 응답 → UI 업데이트였다면 UI 업데이트 → 서버 요청 → 응답으로 사용자 입장에서 빠르게 변경사항을 확인할 수 있어 사용자 경험을 보다 좋게 할 수 있는 전략이다.




react-query로 낙관적 업데이트 구현하기

const UpdateDiary = (studyId: string) => {
  const queryClient = useQueryClient();
  return useMutation(
    async (newDiary: IDiary) => {
      const response = await instance.put(
        `/study/${studyId}/diary/${newDiary.id}`,
        newDiary
      );
      return response;
    },
    {
      onMutate: async (newDiary) => {
        // 1. 쿼리 get 요청 취소 (이전 데이터가 업데이트 데이터 덮어쓰기를 방지)
        await queryClient.cancelQueries(["diaryList", studyId]);
        // 2. 이전 값 저장
        const prevDiaryList: IDiary[] =
          queryClient.getQueryData(["diaryList", studyId]) || [];
        // 3. 낙관적 업데이트
        queryClient.setQueryData(["diaryList", studyId], () =>
          prevDiaryList?.map((diary) =>
            diary.id === newDiary.id ? { ...diary, ...newDiary } : diary
          )
        );
        return { prevDiaryList };
      },
      // 에러 발생 시 롤백
      onError: (error, newDiary, context) => {
        if (context?.prevDiaryList) {
          queryClient.setQueryData(
            ["diaryList", studyId],
            context.prevDiaryList
          );
        }
      },
      onSettled: () => {
        // 요청 성공 여부와 상관없이 쿼리를 무효화해 최신 데이터를 받아오도록 한다.
        queryClient.invalidateQueries(["diaryList", studyId]);
      },
    }
  );
};
  1. onMutate 는 mutate 함수가 실행되기 전에 호출된다.
    • queryClient.cancelQueries(key) 로 낙관적 업데이트로 변경된 데이터를 refetch에 의해 이전 데이터로 덮어쓰지 않도록 방지한다.
    • queryClient.getQueryData(key) 로 이전 데이터를 저장한다.
    • queryClient.setQueryData(key,newData) 로 데이터를 변경시킨다.
    • return { 이전 데이터 } 로 이전 데이터를 반환한다. 이는 서버 요청에서 에러가 발생했을 때 롤백 시키기 위함이다. 이전 데이터는 onErrorcontext 안에 들어간다.
  1. onError 는 요청이 실패하였을 때 호출되는 함수이다. ( 세 번째 인자에 context가 위치한다. )
    • queryClient.setQueryData(key,이전 데이터) 로 요청이 실패하였을 때 이전 값으로 되돌린다.
  1. onSettled 는 요청의 성공 유무와 상관없이 호출되는 함수이다.
    • queryClient.invalidateQueries(key) 를 통해 쿼리를 무효화 시켜 새로운 값을 불러오게 한다.
profile
나는야 프린이

0개의 댓글