optimistic-ui

양세희·2022년 6월 22일
0
post-custom-banner


freeboard에서 구현했던 좋아요 기능을 생각해보자.

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

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

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

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

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

단순히 좋아요를 하나 늘려주는 기능이지만 그 속에는 이렇게 많은 과정이 있다.
이런 부분을 개선하기 위해 사용할 수 있는 것이 Optimistic UI이다.

Optimistic UI

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

즉 좋아요 버튼을 클릭했을 때 성공했다고 간주하고 바로 갯수를 하나 늘려준다.

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

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

Optimistic 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를 이용한다.

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

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

apollo client는 다시 이를 알아차리고 연관된 컴포넌트를 re-rendering한다.

post-custom-banner

0개의 댓글