TIL 88. Optimistic Update

isk·2023년 3월 13일
0

TIL

목록 보기
87/122
post-custom-banner

가끔 invalidateQueries가 먹히지 않을 때가 있었다.
먹히지 않으니 변경사항이 보여지는 게 아닌, 변경되기 전 사항을 보여주게 된다.

invalidate 메서드가 호출되면, React Query는 다음과 같은 작업을 한다고 한다.

캐시된 데이터를 유효하지 않게 표시하고
만료된 데이터가 존재하는 경우, 이전 데이터를 반환할 수 있도록 stale 상태로 변경하며,
백그라운드에서 캐시를 다시 가져오는 비동기 작업을 시작한다.
따라서 invalidate 메서드가 호출되었을 때 즉시 데이터가 갱신되지 않을 수 있다.
대신, React Query가 다음 요청을 할 때 데이터가 새로 고쳐질 것이라고 한다.

그래서 사용자에게 변경될 데이터를 미리 보여주는 낙관적 업데이트(Optimistic Update)를 사용해보려고 한다.

import { dbService } from '@/firebase';
import { doc, getDoc, increment, updateDoc } from 'firebase/firestore';
import React from 'react';
import { useMutation, useQuery, useQueryClient } from 'react-query';

function Index() {
  const queryClient = useQueryClient();
  // 파이어베이스 테스트 데이터
  const getTest = async () => {
    const data = await getDoc(doc(dbService, 'test', 'number'));
    return data.data();
  };
  // 1 더하기
  const plusNumber = async () => {
    await updateDoc(doc(dbService, `test/number`), { count: increment(1) });
  };

  // 테스트 데이터 가져오기
  const { data } = useQuery('testData', getTest);

  const { mutate } = useMutation(plusNumber, {
    onMutate: async () => {
      await queryClient.cancelQueries('testData');
      const oldItemData = queryClient.getQueryData('testData');
      queryClient.setQueryData('testData', (old: any) => ({
        // count: old.count + 1,
        count: 2, // 사용자가 보게 될 데이터
      }));
      return { oldItemData };
    },
    onError: (err, values, context) => {
      queryClient.setQueryData('testData', context?.oldItemData);
    },
    onSettled: async () => {
      await queryClient.invalidateQueries('testData');
    },
  });

  const onClickPlus = () => {
    mutate();
  };
  return (
    <div>
      <div>{data?.count}</div>
      <div>
        <button onClick={onClickPlus}>더하기</button>
      </div>
    </div>
  );
}

export default Index;

위 코드는 더하기 버튼을 눌렀을 때, 숫자를 +1시킨다.
하지만 데이터베이스에 +1이 되고, 더한 숫자를 가져와서 브라우저에 보여지기 전까지 사용자가 보는 숫자는 2다.
그래서 느리게 보면, 숫자 2가 먼저 보이고 나중에 +1이 된 숫자를 볼 수 있다.
사용자가 볼 데이터의 캐시 데이터를 조작해서 먼저 보여주고, 뒤에서 업데이트 된 데이터를 가져오는 방식이라고 한다.

post-custom-banner

0개의 댓글