[React] useOptimistic hook

2024. 11. 18. 14:35·Frontend/Memo
반응형

 

useOptimistic (state, updateFn)

: 사용자가 폼을 제출할 때(네트워크 요청과 같은 백그라운드 작업이 완료되기 전),

  서버의 응답을 기다리는 대신 UI를 기대하는 결과로 즉시 업데이트하여 유저에게 보여주고 싶을 때 사용한다.

 

 

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

 

 

useOptimistic은 비동기 작업이 진행 중일 때 다른 상태를 보여줄 수 있게 해주는 React hook입니다.

현재 상태와 작업의 입력을 취하는 함수를 제공하고, 작업이 대기 중일 때 사용할 상태를 반환합니다.

 

이 상태는 “낙관적” 상태라고 불리는데, 실제로 작업을 완료하는 데 시간이 걸리더라도

사용자에게 즉시 작업의 결과를 표시하기 위해 일반적으로 사용됩니다.

 

import { useOptimistic } from 'react';

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

매개변수

  • state: 작업이 대기 중이지 않을 때 초기에 반환될 값입니다.
  • updateFn(currentState, optimisticValue): 현재 상태와 addOptimistic에 전달된 낙관적인 값을 취하는 함수로, 결과적인 낙관적인 상태를 반환합니다. 순수 함수여야 합니다. updateFn은 두 개의 매개변수를 취합니다. currentState와 optimisticValue. 반환 값은 currentState와 optimisticValue의 병합된 값입니다.

반환값

  • optimisticState: 결과적인 낙관적인 상태입니다. 작업이 대기 중이지 않을 때는 state와 동일하며, 그렇지 않은 경우 updateFn에서 반환된 값과 동일합니다.
  • addOptimistic: addOptimistic는 낙관적인 업데이트가 있을 때 호출하는 dispatch 함수입니다. 어떠한 타입의 optimisticValue라는 하나의 인자를 취하며, state와 optimisticValue로 updateFn을 호출합니다.

 

 

사용예시

'use client'

import { dislikePost, likePost } from '@/app/posts/[id]/actions'
import { useOptimistic } from 'react'

const Button = ({ isLiked, likeCount, postId }: IProps) => {
  const [state, reducerFn] = useOptimistic(
    // state
    { isLiked, likeCount },

    // reducer function
    (prev, payload) => ({
      // db 응답오기전에 보여줄 UI 정보
      isLiked: !prev.isLiked,
      likeCount: prev.isLiked ? prev.likeCount - 1 : prev.likeCount + 1,
    }),
  )

  const onClick = async () => {
    // reducerFn을 먼저 작동시켜서 서버 응답 오기전에 지정한 UI를 먼저 보여줌
    reducerFn(undefined)

    if (isLiked) {
      await dislikePost(postId)
    } else {
      await likePost(postId)
    }
  }

  return (
      <button onClick={onClick} >
        {state.isLiked ? (
          <span> {state.likeCount}</span>
        ) : (
          <span>공감하기 ({state.likeCount})</span>
        )}
      </button>
  )
}

export default Button
반응형

'Frontend > Memo' 카테고리의 다른 글

[Vitest] React Testing library  (0) 2025.06.15
Package manager - Yarn PnP(Plug'n'Play)란?  (0) 2024.12.12
Supabase으로 실시간 채팅기능 만들기 (Real-time database)  (2) 2024.11.19
'Frontend/Memo' 카테고리의 다른 글
  • [Vitest] React Testing library
  • Package manager - Yarn PnP(Plug'n'Play)란?
  • Supabase으로 실시간 채팅기능 만들기 (Real-time database)
manon_e
manon_e
  • manon_e
    개발 블로그
    manon_e
  • 전체
    오늘
    어제
    • 💻 (109)
      • Frontend (10)
        • React | Next.js (6)
        • Memo (4)
      • CS (5)
        • 네트워크 (0)
        • 자료구조 + 알고리즘 (3)
        • 컴퓨터 구조 + 운영체제 (2)
      • Cloud & Infra (2) N
      • Project (5)
      • Archive (87)
  • 인기 글

  • 태그

    티스토리챌린지
    오블완
    vscode
    REACT
    비동기
    JavaScript
    Component
    Node
    ES6
    Next.js
    axios
    정규표현식
    node.js
    typeScript
    pre-rendering
    getstaticprops
    useEffect
    State
    git
    Prisma
  • hELLO· Designed By정상우.v4.10.3
manon_e
[React] useOptimistic hook
상단으로

티스토리툴바