optimistic-ui

ssummer·2023년 9월 15일
post-thumbnail

컴퓨터가 느린 환경에 있거나 백엔드 서버가 물리적으로 멀리 있다면 mutation 요청을 하고 응답을 받는데까지 시간이 오래 걸릴 수 있다. 가령 좋아요 버튼을 누르는 간단한 요청을 보냈는데 응답이 2-3초 걸린다면 사용자 경험에 굉장히 좋지 않은 영향을 끼칠 것이다. 이럴 때 optimistic-ui를 사용하게 된다.

optimistic-ui

optimistic-ui는 요청을 보냄과 동시에 글로벌 스테이트를 변경하고 화면의 값을 바꾸는 것이다. 요청이 성공하면 응답으로 들어온 결과값으로 화면을 업데이트한다. 하지만 optimistic-ui로 이미 화면의 값은 바뀌어있기 때문에 사용자가 보기엔 똑같다.

요청이 실패하게 되면 이전의 값을 응답으로 보내주게 되고 그 값으로 화면을 업데이트 한다.

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(): JSX.Element {
  const { data } = useQuery<Pick<IQuery, "fetchBoard">, IQueryFetchBoardArgs>(
    FETCH_BOARD,
    {
      variables: { boardId: "board id" },
    },
  );

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

  const onClickLike = (): void => {
    void likeBoard({
      variables: {
        boardId: "board id",
      },
      //   refetchQueries: [{}],
      optimisticResponse: {
        likeBoard: (data?.fetchBoard.likeCount ?? 0) + 1,
      },
      update: (cache, { data }) => {
        cache.writeQuery({
          query: FETCH_BOARD,
          variables: { boardId: "board id" },
          data: {
            fetchBoard: {
              _id: "board id",
              __typename: "Board",
              likeCount: data?.likeBoard, // optimisticResponse에서 받아온 Data
            },
          },
        });
      },
    });
  };

  return (
    <>
      <div>현재 카운트(좋아요) : {data?.fetchBoard?.likeCount}</div>
      <button onClick={onClickLike}>좋아요 올리기!</button>
    </>
  );
}

optimisticResponse 옵션을 사용해 작성한다.

optimistic-ui실패 확률이 낮고 중요도가 낮은 요청에만 사용하도록 한다. 사용자에게 만족도 높은 경험을 줄 수 있기에 중요하지 않은 요청이라면 optimistic-ui를 사용하는 것이 좋다.

0개의 댓글