ougi FE

낙관적 업데이트에 대해서 알아보자 본문

React

낙관적 업데이트에 대해서 알아보자

ougi 2025. 7. 26. 18:03

오늘은 개발하다가 친구가 모든 코드에 이 낙관적 업데이트를 적용 해놓은 걸 보았습니다..

근데 저의 생각으로는 이렇게 모든 곳에 낙관적 업데이트를 적용하는게 바르지 않다고 생각하여서

이게 무엇이고 어떻게 하는지 구체적으로 알아보려 합니다


낙관적 업데이트란?

낙관적 업데이트는 웹 애플리케이션에서 사용자 경혐을 향상시키기 위해 사용되는 개념이라고 합니다

주로 네트워크 요청이나 데이터 업데이트와 관련하여 사용합니다

낙관적 업데이트는 서버로 보낸 요청이 정상적일 것이라고 미리 예상하고

클라이언트 요청에 대한 응답이 오기 전에 클라이언트의 데이터를 미리 업데이트 된 상태로 변경하는 작업을 말합니다

장점

  • 사용자가 행동을 하면 즉각적으로 피드백이 되어서 사용자 경험이 향상됩니다

단점

  • 만약 오류가 발생한다면 ui가 잠깐이라도 불일치할 수도 있습니다
  • 실패 시 원래대로 돌리는 추가 로직이 필요합니다
  • 데이터 정합성이 떨어질 수 있습니다

낙관적 업데이트 하는 법

일단 낙관적 업데이트를 하는 법 중에 저는 tansctack-query로 낙관적 업데이틀 하는 법을 알려드리겠습니다

일단 코드를 보기 전에 흐름을 말해보자면

  1. 사용자의 액션이 발생합니다
  2. 클라이언트에서 ui 업데이트를 합니다
  3. 비동기 요청을 서버로 전송합니다
  4. 서버 응답이 성공이면 그대로 유지하고, 실패하면 ui를 이전의 ui로 되돌립니다
import { useMutation, useQueryClient } from '@tanstack/react-query';
import { deletePost } from '../api/deletePost';
import { toast } from 'sonner';

export const useDeletePost = () => {
  const queryClient = useQueryClient();

  return useMutation({
    mutationFn: (id: string) => deletePost(id),

    onMutate: async (id: string) => {
      await queryClient.cancelQueries({ queryKey: ['notice'] }); // 이전 캐시 지우기

      const previousData = queryClient.getQueryData(['notice']); // 변경되기 전 데이터 저장

      queryClient.setQueryData(['notice'], (old: any[] | undefined) =>
        old?.filter((post) => post.id !== id),
      ); // 미리 없애고 저장

      return { previousData };
    },

    onError: (err, id, data) => {
      if (data?.previousData) {
        queryClient.setQueryData(['notice'], data.previousData); // 이전 데이터로 다시 돌리기
      }
      toast.error('게시글 삭제에 실패했습니다');
    },

    onSuccess: () => {
      toast.success('게시글이 삭제되었습니다');
    },

    // 작업이 끝나면 쿼리를 다시 가져옴 확실하게 fresh한 상태를 갖기 위해
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ['notice'] });
    },
  });
};

 


글을 마치며

이렇게 낙관적 업데이트에 대해서 알아보고 글을 써보았는데 제가 처음에 생각했던 것처럼 모든 곳에 불필요하게

낙관적 업데이트를 다 적용한 것은 부적절했던거 같습니다

즉각적으로 바로 피드백이 필요한 경우에만 사용하면 좋은 사용자 경험을 제공할 수 있을거 같습니다

글을 읽어주셔서 감사합니다

728x90