Optimistic-UI

남예지·2022년 12월 15일
0
post-thumbnail

Optimistic-UI란?
낙관적 UI는 UI에 바쁜 스피너를 표시하지 않고 애플리케이션이 서버에서 데이터를 변경하는 사용자 상호 작용에 즉시 응답하는 것처럼 느끼게 하는 패턴입니다. 처리할 서버로 만드는 데 시간이 좀 걸리더라도 UI에 충분한 정보를 보내서 가짜로 보내는 경우가 많습니다. 어떤 이유로 실패하면 사용자에게 문제가 있음을 알릴 수 있습니다. 대부분의 경우 실패하지 않으며 앱은 사용자의 상호 작용에 즉시 응답할 수 있습니다.

우리가 좋아요를 클릭하면 원래는 많은 단계가 있지만 아폴로캐시에서 다음 숫자를 생각해서 미리 보여주고 요청을 해서 숫자가 먼저 바뀌고 난 다음에 데이터베이스에서 변경을 한다.

예시로 좋아요가 8이 있다면 눌렀을때 9가 되겠지 하고 예상해서 누르면 9라는 숫자를 먼저 보여주고 데이터를 백엔드에 보내는것이다.
만약 백엔드나 디비에서 에러가 떨어지면 아폴로캐시에서 원상복귀하고 9로 바뀌었다가 8로 다시 돌아간다.
실패 시 올라갔다가 줄어드는 좋지 못한 UX를 보여준다.
그래서 Optimistic-UI는 항상 사용하지 않고 99% 성공을 확신할 수 있을때/만약 실패해도 별 상관이 없을 때 사용을 해야한다.

import { useMutation, useQuery, gql } from "@apollo/client";
import {
  IMutation,
  IMutationLikeBoardArgs,
  IQuery,
  IQueryFetchBoardArgs,
} from "../../src/commons/types/generated/types";

const FETCH_BOARD = gql`
  query fetchBoard($boardId: ID!) {
    fetchBoard(boardId: $boardId) {
      _id
      likeCount
    }
  }
`;
const LIKE_BOARD = gql`
  mutation likeBoard($boardId: ID!) {
    likeBoard(boardId: $boardId)
  }
`;

export default function OptimisticUiPage() {
  const { data } = useQuery<Pick<IQuery, "fetchBoard">, IQueryFetchBoardArgs>(
    FETCH_BOARD,
    { variables: { boardId: "639a7d25531bd200286b7836" } }
  );

  const [likeBoard] = useMutation<
    Pick<IMutation, "likeBoard">,
    IMutationLikeBoardArgs
  >(LIKE_BOARD);

  const onClickLike = () => {
    void likeBoard({
      variables: { boardId: "639a7d25531bd200286b7836" },
      update: (cache, { data }) => {
        cache.writeQuery({
          query: FETCH_BOARD,
          variables: { boardId: "639a7d25531bd200286b7836" },
          data: {
            fetchBoard: {
              _id: "639a7d25531bd200286b7836",
              __typename: "Board",
              likeCount: data?.likeBoard,
            },
          },
        });
      },
    });
  };
  return (
    <>
      <div>현재카운트(좋아요) : {data?.fetchBoard.likeCount} </div>
      <button onClick={onClickLike}>좋아요 올리기</button>
    </>
  );
}

이렇게만 하면 느린 3g로 돌렸을 때 한참 있다가 카운트가 올라가는 걸 볼 수 있다.

하지만 Optimistic-UI를 한줄 추가해주면 처리되기 전 먼저 카운트가 올라가는 걸 볼 수 있다.

    optimisticResponse: {
          likeBoard: (data?.fetchBoard.likeCount ?? 0) + 1,
        },

이 코드를 onClickLike 함수안에 update 윗줄에 넣어주면 된다.


(연타해보았는데 99까지 먼저 올라가고 네트워크탭에서는 아직 대기중인걸 볼 수 있다!)

좋아요 같은 기능에 넣어주면 좋겠다.

profile
총총

0개의 댓글