본문 바로가기

Computer Programming/Next

[Next.js] Optimistic UI 구현 (좋아요, 북마크 기능 개선)

Optimistic UI는 API에 요청을 보낸 후 UI를 그려내는 과정에서 모든 것을 낙관적으로 보고 UI를 먼저 그리는 모델이다.

 

다시 정리하자면, 옵티미스틱 UI는 모든 API 통신이 성공할 것이라 여기고 화면에 먼저 결과 값을 그리는 것을 말한다.

 

성공확률이 99%정도 되는 요청엔 적용해줘도 되지 않을까..?

(좋아요, 북마크는 메인페이지 -> 상세페이지에 접근한 후 가능한데, 상세 페이지

 

유저가 좋아요나 북마크 버튼을 누를 때 아래와 같은 onSubmit 함수가 실행된다.

const onSubmitOption = async (type: string) => {
    try {
      const res = await fetch(
        `${process.env.NEXT_PUBLIC_NEXT_SERVER}/api/${type}?articleId=${articleId}`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
        },
      );
    } catch (e) {
      console.log(e);
    }
  };

그리고나서 서버의 상황을 반영하기 위해 (즉 좋아요 수 +1, user.bookmarked를 true로 변경 등) 

원래는 window.location.reload() 함수를 실행시켜 새로고침 했다.

새로고침 하면 새로운 상태의 데이터 상태가 반영되어 좋아요에 하트가 채워지는 방식으로 구현했다.

 

넥스트가 아무리 get요청 캐싱으로 속도가 빠르다지만... 인스타그램이나 페이스북 처럼 좋아요버튼을 누르면 깜빡거림 없이 바로 하트가 채워지게끔 구현하고 싶어서 optimistic ui를 적용해봤다.

 

 

방법은 간단한데, useState과 같은 상태 관리 도구를 이용하면 된다. 

다만 문제는 좋아요와 북마크의 상태를 공유하는 컴포넌트가 두개였다는 것...

여기서 오른쪽 윗 부분과

 

글 가장 아래에 좋아요 버튼을 누를 수 있는 컴포넌트로 나누어져 있었다.

 

그래서 다른 페이지에도 사용하고 있던 리코일을 활용해서 전역상태관리로 적용했다.

 

import { atom } from 'recoil';

export const heartedPostState = atom<boolean>({
  key: 'heartedPostState',
  default: false,
});

export const bookmarkedPostState = atom<boolean>({
  key: 'bookmarkedPostState',
  default: false,
});

export const heartCountState = atom<number>({
  key: 'heartedCountState',
  default: 0,
});

export const bookmarkCountState = atom<number>({
  key: 'bookmarkedCountState',
  default: 0,
});

 

각 요소의 boolean 값과 count를 따로 관리해줬다.

 

그리고 나서 onSubmitHandler에 useRecoilSetState함수를 이용해 값을 변경했다.

 

 

const onSubmitOption = async (type: string) => {
    try {
      const res = await fetch(
        `${process.env.NEXT_PUBLIC_NEXT_SERVER}/api/${type}?articleId=${articleId}`,
        {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
        },
      );
      if (type === 'like') {
        setHeartCount((prev) => (hearted === false ? prev + 1 : prev - 1));
        setHearted(!hearted);
      } else {
        setBookmarkCount((prev) =>
          bookmarked === false ? prev + 1 : prev - 1,
        );
        setBookmarked(!bookmarked);
      }
    } catch (e) {
      console.log(e);
    }
  };

 

 

 

-----

Reference

https://idealstring.tistory.com/49

 

Optimistic-UI

옵티미스틱 UI(Optimistic-UI)는 멘털 모델 중 하나다. 인터페이스 형태를 말하는 게 아니다. API와 통신 중 UI를 그려내는 과정에서 모든 것을 낙관적으로 보고 UI를 먼저 그리는 모델이다. 다시 정리

idealstring.tistory.com

https://velog.io/@jhjung3/Optimistic-Updates-%EA%B5%AC%ED%98%84%ED%95%98%EA%B8%B0-with-%EB%A6%AC%EC%95%A1%ED%8A%B8-%EC%BF%BC%EB%A6%AC

 

UX 향상을 위한 Optimistic Updates 구현하기 (with 리액트 쿼리)

페이스북이나 인스타그램에서 "좋아요" 기능을 사용해본 경험이 있으신가요?

velog.io