[Hook] useOptimistic

OlMinJe·2025년 9월 2일

React

목록 보기
13/19

리액트 공식 문서를 참고한 정리 내용 (25.08 기준)

UI를 낙관적으로 업데이트할 수 있게 해주는 Hook이다.

const [optimisticState, addOptimistic] = useOptimistic(state, updateFn);

네트워크 요청이나 비동기 작업 때문에 사용자가 결과를 바로 보지 못하고 기다려야 하는 경우가 많은데, 이걸 보는 사용자는 답답할 수 있다. 이럴 때 사용하는 게 useOptimistic 훅이다

이름 그대로 “낙관적인 상태(optimistic state)”를 보여주는 훅이다. 즉, 작업이 끝날 때까지 기다리지 않고 마치 이미 성공할 것처럼 결과를 화면에 먼저 보여줄 수 있도록 도와주는 역할을 수행한다.

역할 수행 방식은 (1)현재 상태와 작업 입력값을 받는다.그리고 (2)비동기 작업이 진행되는 동안, “낙관적인 상태”라는 가짜 복사본을 만들어서 반환한다. 마지막으로 (3)실제 작업이 끝나면 진짜 상태로 교체된다.

import { useOptimistic } from 'react';

function AppContainer() {
  const [optimisticState, addOptimistic] = useOptimistic(
    state,
    // updateFn
    (currentState, optimisticValue) => {
      // merge and return new state
      // with optimistic value
    }
  );
}

매개변수

state

  • 처음에 보여줄 기본 상태 값이다. (비동기 작업이 진행되지 않을 떄의 원래 상태)

udateFn(currentState, optimisticValue)

  • 낙관적인 상태를 만들어주는 함수로 순수 함수여야 한다.
  • 지금까지의 실제 상태
  • optimisticValue은 함수에 전달한 새로운 값이며, currentState와 합쳐서 “낙관적인 결과 상태”를 만들어서 반환하면 된다.

👉 updateFn"기존 상태 + 새 값 = 낙관적인 상태" 로 만드는 함수 |

const [optimisticComments, addOptimisticComment] = useOptimistic(
  [], // state: 기본 상태 → 처음엔 빈 배열
  (currentComments, newComment) => [...currentComments, newComment]
  // updateFn: 지금까지 댓글 + 새 댓글을 합쳐서 반환
);

반환값

optimisticState

  • 지금 화면에 보여줄 낙관적인 상태이며, 작업이 진행 중이 아니면 그냥 원래 상태(state)를 보여준다. 작업이 진행 중이면 updateFn이 만들어낸 가짜 상태(optimistic)를 보여준다.

addOptimistic

  • 새로운 낙관적인 값을 추가하고 싶을 떄 사용하는 함수이다.
  • 인자로 optimisticValue (ex. 새 댓글, 좋아요 누름 등)를 넘기면 state와 합쳐져서 optimisticState가 업데이트 된다

사용법

폼을 낙관적으로 업데이트하기

보통은 사용자가 폼을 제출하면서버에 요청을 보낸 뒤응답이 돌아올 때까지 기다려야 화면이 업데이트 된다.
하지만 이렇게 하면 사용자 입장에서는 “버튼 눌렀는데 왜 바로 반응이 없지?"하고 답답할 수 있다.

이럴 때 useOptimistic을 사용하면, 서버 응답을 기다리지 않고도 먼저 화면을 바꿔 보여줄 수 있다. 마치 결과를 미리 예측해서 보여주는(=낙관적인) 방식이다.

메시지 전송을 예시로 들어보자

  1. 사용자가 메시지를 입력하고 “전송” 버튼을 누른다.
  2. 서버 응답을 기다리지 않고, 화면세는 바로 “보내는 중…” 표시가 달린 메시지가 나타난다.
  3. 백그라운드에서 서버에 실제 메시지를 보낸다
  4. 서버가 확인을 보내면 → “보내는 중” 표시가 사라지고 정상 메시지로 바뀐다.
import { useState, useOptimistic } from "react";

function CommentForm({ onAdd }) {
  const [text, setText] = useState("");
  // 낙관적 상태 관리: 새로운 댓글을 바로 UI에 추가
  const [optimisticComments, addOptimisticComment] = useOptimistic(
    [], 
    (state, newComment) => [...state, newComment]
  );

  async function handleSubmit(e) {
    e.preventDefault();
    const comment = { id: Date.now(), text };

    // 낙관적 업데이트 (서버 응답 기다리기 전에 먼저 추가)
    addOptimisticComment(comment);

    // 실제 서버 저장 요청
    await onAdd(comment);

    setText("");
  }

  return (
    <form onSubmit={handleSubmit}>
      <input 
        value={text} 
        onChange={e => setText(e.target.value)} 
        placeholder="Write a comment" 
      />
      <button type="submit">Add</button>

      <ul>
        {optimisticComments.map(c => (
          <li key={c.id}>{c.text}</li>
        ))}
      </ul>
    </form>
  );
}

이러한 점은 사용자 입장에서 어플리케이션이 빠르게 느껴지고, 네트워크 지연이 있어도 “즉시 반응”하는 것처럼 보이니까 UX가 매끄러워진다.

profile
큐트걸

0개의 댓글