[React] Optimistic Updating

SungWoo·2024년 11월 17일

React

목록 보기
10/16
post-thumbnail

사용자가 서버에 데이터를 전송할 경우, 서버가 업데이트를 확인하기 전에 UI의 변경 사항을 즉시 반영한다면 사용자 경험이 훨씬 향상 될 것이다.

이때 Optimistic Updating(낙관적 업데이트)라는 기술을 사용할 수 있다.

Optimistic Updating

서버에 side effect를 발생시키는 요청에 대해, 요청을 보내는 것과 동시에 결과를 예측하고, 예측한 결과를 UI에 반영하는 것

낙관적 업데이트를 구현할 때 두 가지 주요 전략을 사용할 수 있다.

1. UI를 직접 변수로 업데이트

  • 적합한 경우: UI의 한 곳에서만 업데이트를 반영할 때
  • 특징
    • 간단하고 코드가 적다.
    • 서버 실패 시에도 롤백 처리가 불필요하다.
  • 방법: 상태 변수 등으로 UI를 직접 업데이트

2. 캐시 조작

  • 적합한 경우: 업데이트 내용을 UI 여러 곳에서 공유해야 할때
  • 특징
    • 모든 관련 UI 구성 요소가 자동으로 낙관적 업데이트를 반영하도록 함
    • 서버 업데이트 실패 시, 이전 상태로 롤백 가능
  • 방법: 캐시를 수정하여 UI를 변경하고, 실패 시 복구

React Query로 Optimistic Update 구현하기

useMutation 훅을 사용하여 할 일(ToDo) 업데이트하기

import { useMutation, useQueryClient } from 'react-query';

const queryClient = useQueryClient();

useMutation({
  mutationFn: updateTodo, // 서버 업데이트 함수
  onMutate: async (newTodo) => {
    // 1. 기존 쿼리 취소 (새 요청이 들어왔기 때문에)
    await queryClient.cancelQueries({ queryKey: ['todos', newTodo.id] });

    // 2. 이전 데이터 저장 (rollback 대비)
    const previousTodo = queryClient.getQueryData(['todos', newTodo.id]);

    // 3. 캐시에 새로운 데이터로 업데이트 (Optimistic Update)
    queryClient.setQueryData(['todos', newTodo.id], newTodo);

    // 4. 컨텍스트로 이전 데이터 반환 (rollback에 사용)
    return { previousTodo, newTodo };
  },
  onError: (err, newTodo, context) => {
    // 서버 업데이트 실패 시, 캐시를 이전 상태로 복구
    queryClient.setQueryData(['todos', context.newTodo.id], context.previousTodo);
  },
  onSettled: (newTodo) => {
    // 서버 처리 완료 후, 쿼리를 다시 가져와 최신 상태로 동기화
    queryClient.invalidateQueries({ queryKey: ['todos', newTodo.id] });
  },
});

코드 설명

  1. onMutate
  • 서버 요청 전에 캐시를 먼저 업데이트
  • 이전 데이터를 저장해두어 서버 실패 시 복구 가능
  1. onError
  • 서버 업데이트가 실패하면 저장해둔 이전 데이터를 캐시에 복원
  1. onSettled
  • 성공 실패와 관계 없이 최신 데이터를 가져오도록 쿼리 재요청

요약

  • 사용자 경험(UX) 개선
  • 여러 컴포넌트에서 상태를 자동 동기화
  • 실패 시에도 데이터 안정성 보장
profile
어제보다 더 나은

0개의 댓글