[TIL] 10월 21일 Optimistic UI

기록하며 공부하자·2021년 10월 23일
1

자유게시판의 좋아요 기능을 클릭했을시의 동작을 살펴보면 아래와 같다.

  1. 사용자가 좋아요 버튼을 누른다.

  2. onClick 함수가 실행되고 서버에 mutation 요청을 보낸다.

  3. 서버에 보낸 요청이 완료될 때까지 await으로 기다린다.

  4. 완료가 되었으면 refetch로 좋아요 갯수 데이터를 다시 가져온다.

  5. 가져온 데이터를 화면에 보여준다.

좋아요 기능을 생각하면 상당히 단순히 좋아요의 갯수를 +1 해주는 기능인데 이렇게 많은 과정을 거쳐야 한다.

이부분을 개선하기 위해서 Optimistic UI를 사용할수 있다.

Optimistic UI

Optimistic UI는 단어 그대로 낙관적으로 생각하는 UI 이다.

즉 좋아요 버튼을 클릭했을시 성공했다고 간주하고 바로 갯수를 +1 해준다.

혹시라도 좋아요 기능이 실패한다면 조용히 원래상태로 되돌린다.

Optimistic UI는 기본적으로 성공했다고 간주하는 것이기 때문에 중요한 기능에서는 사용 못하고 좋아요 기능처럼 단순한 기능에 사용할수 있다.

Optimisitc UI 적용 예제코드

import { gql, useMutation, useQuery } from "@apollo/client";
import { update } from "lodash";

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

const LIKE_BOARD = gql`
  mutation likeBoard($boardId: ID!) {
    likeBoard(boardId: $boardId)
  }
`;

export default function OptimisticUIPage() {
  const [likeBoard] = useMutation(LIKE_BOARD);

  const { data } = useQuery(FETCH_BOARD, {
    variables: { boardId: "612f4257abd89b00293adda7" },
  });

  const onClickLike = () => {
    likeBoard({
      variables: { boardId: "612f4257abd89b00293adda7" },
      //   refetchQueries: [
      //     {
      //       query: FETCH_BOARD,
      //       variables: { boardId: "612f4257abd89b00293adda7" },
      //     },
      //   ],

      // 리패치 될때까지 기다려야함
      optimisticResponse: {
        likeBoard: data?.fetchBoard.likeCount + 1,
      },
      update(cache, { data }) {
        cache.writeQuery({
          query: FETCH_BOARD,
          variables: { boardId: "612f4257abd89b00293adda7" },
          data: {
            fetchBoard: {
              likeCount: data.likeBoard,
            },
          },
        });
      },
    });
  };

  return (
    <>
      <div>좋아요 갯수: {data?.fetchBoard.likeCount}</div>
      <button onClick={onClickLike}>좋아요 올리기!</button>
    </>
  );
}

기존에는 refetchQueries를 통해 완료시 다시 화면을 그려줬지만 optimisticResponse을 이용한다.

optimistcResponse에 적은 내용이 아폴로 클라이언트 캐시에 optimistic 버전으로 저장되면 아폴로 클라이언트는 이를 알아차려 저장된 데이터를 가지고 연관된 컴포넌트를 다시 랜더링 한다.

서버의 응답으로 진짜 데이터를 받으면, 아폴로 클라이언트는 기존의 optimistic 버전을 지우고 서버에서 받은 데이터를 저장한다.

아폴로 클라이언트는 다시 이를 알아차리고 연관된 컴포넌트를 다시 랜더링 한다.

profile
프론트엔드 개발자 입니다.

0개의 댓글