react <form>; useOptimistic()

gyubo·2025년 2월 4일

useOptimistic는 React 18+에서 제공되는 훅으로, 낙관적 업데이트(Optimistic UI)를 구현할때 사용한다. 낙관적 업데이트란, 서버로 요청을 보내기 전에 사용자 인터페이스(UI)를 미리 업데이트해 즉각적인 반응성을 제공하는 것 이다.

낙관적 업데이트란?

서버 요청이 성공할 것이라고 가정하고, UI를 즉시 업데이트하여 더 나은 사용자 경험(UX)을 제공.
예: "좋아요" 버튼 클릭 시 서버에 요청하기 전에 버튼의 상태를 변경하는 동작.
useOptimistic의 역할

로컬 상태와 낙관적 상태를 동시에 관리.

서버 요청 전후의 상태를 직관적으로 업데이트 가능.
UI가 서버 요청의 성공/실패와 관계없이 자연스럽게 동작하도록 보여짐.

사용법

useOptimistic는 두 개의 값을 반환한다 :
[optimisticState, updateOptimisticState]:
optimisticState: 현재 상태 (초기값을 기준으로 생성).
updateOptimisticState: 상태를 업데이트하는 함수.

const [optimisticState, updateOptimisticState] = useOptimistic(initialState, updateFn);

initialState: 초기 상태 값.
updateFn: 낙관적 상태를 업데이트하는 함수.

"좋아요" 버튼 구현 예제

'use client';

import React, { useTransition, useOptimistic } from 'react';

export default function LikeButton({ postId }) {
  // Transition 상태 추적 (서버 요청 중인지 확인)
  const [isPending, startTransition] = useTransition();

  // useOptimistic 훅으로 낙관적 상태 관리
  const [likes, updateLikes] = useOptimistic(0, (currentLikes, delta) => currentLikes + delta);

  // "좋아요" 상태 변경 함수
  const handleLike = () => {
    // 낙관적 상태 업데이트
    updateLikes(1);

    // 서버 요청 시작
    startTransition(async () => {
      try {
        await fetch(`/api/like/${postId}`, { method: 'POST' });
        console.log('Server updated successfully');
      } catch (error) {
        console.error('Server error, reverting state');
        updateLikes(-1); // 서버 실패 시 상태 복원
      }
    });
  };

  return (
    <button onClick={handleLike} disabled={isPending}>
      {isPending ? 'Liking...' : `👍 ${likes} Likes`}
    </button>
  );
}

동작 원리

초기 상태 설정: useOptimistic에서 초기 상태(예: 좋아요 수)를 설정.
UI 즉각 업데이트: updateOptimisticState를 호출해 낙관적 상태를 업데이트. UI는 즉시 변경됨.
서버 요청 처리: useTransition으로 비동기 작업 실행.
오류 처리: 서버 요청이 실패하면 상태를 복원하거나 에러 메시지를 표시.

반응성 높은 UI 제공:

사용자 입력에 즉각적으로 반응해 자연스러운 경험 제공.

낙관적 업데이트 관리 간소화:

상태 업데이트와 로컬 UI 변경을 쉽게 처리.

React 서버 컴포넌트와의 호환성:

비동기 작업과 통합하여 React 18의 기능을 최대한 활용.

- useOptimistic는 로컬 상태와 서버 상태를 동기화하는 데 사용.

- 낙관적 업데이트 실패 시 복구 로직을 추가하는 것이 중요.

- Transition과 함께 사용하면 서버 요청과 UI 업데이트를 명확히 분리 가능.

profile
개린이

0개의 댓글