useOptimistic 훅의 철학이 명확해지자, 문서화 팀은 이 강력한 도구의 활용 사례를 더욱 풍부하게 만들어야 한다는 과제에 직면했다. 지금까지의 모든 예시는 ‘좋아요’ 버튼에 국한되어 있었다. 이래서는 개발자들이 useOptimistic을 단순한 토글(toggle) 기능에만 사용하는 훅으로 오해할 수 있었다.
“우리는 useOptimistic이 훨씬 더 다양한 시나리오에서 사용자 경험을 향상시킬 수 있음을 보여줘야 합니다.”
한 기술 작가가 의견을 냈다. “목록에 아이템을 추가하거나, 댓글을 다는 것처럼 더 복잡한 상태 변화를 다루는 예시가 필요해요.”
그의 제안에 따라, 팀은 새로운 데모 시나리오를 구상하기 시작했다. 그들이 선택한 것은 바로 ‘실시간 댓글 시스템’이었다.
시나리오: 댓글 달기
-
Before (전통적인 방식): 사용자가 댓글을 입력하고 ‘전송’ 버튼을 누른다. 버튼이 비활성화되고 로딩 스피너가 돈다. 서버로부터 성공 응답이 온 후에야, 방금 작성한 댓글이 목록의 맨 아래에 나타난다. 이 과정에서 1~2초의 지연은 흔했다.
-
After (
useOptimistic적용): 사용자가 ‘전송’ 버튼을 누르는 즉시, 입력창은 비워지고 방금 작성한 댓글이 목록에 즉시 추가된다. 다만, 아직 서버에 저장되지 않은 임시 상태임을 알려주기 위해 약간 흐린 회색으로 표시된다. 백그라운드에서 서버 요청이 성공적으로 완료되면, 그 댓글은 다른 댓글들처럼 선명한 검은색으로 바뀐다. 만약 요청이 실패하면, 그 댓글은 목록에서 스르륵 사라지고, 입력창에는 원래의 텍스트가 다시 채워지며 에러 메시지가 표시된다.
이 예시는 useOptimistic이 단순히 boolean이나 숫자 같은 원시 값뿐만 아니라, 객체의 배열 같은 복잡한 데이터 구조도 다룰 수 있음을 명확히 보여주었다.
// comments: [{ id: 1, text: '첫 댓글' }]
// optimisticComments: [{ id: 1, text: '첫 댓글' }, { id: null, text: '내가 쓴 댓글', pending: true }]
const [optimisticComments, addOptimisticComment] = useOptimistic(
comments,
(currentComments, newCommentText) => [
...currentComments,
{ id: null, text: newCommentText, pending: true } // 새로운 임시 객체 추가
]
);
팀은 여기서 멈추지 않고, 더 다양한 활용 사례를 탐구했다.
- 장바구니에 아이템 추가: 사용자가 ‘담기’ 버튼을 누르면, 상품이 즉시 우측 상단의 미니 카트 아이콘으로 날아가 담기는 애니메이션과 함께 카운트가 올라간다. 실제 서버 요청은 백그라운드에서 처리된다.
- 메시지 전송: 채팅 앱에서 메시지를 보내면, 즉시 대화창에 나타나고 옆에는 작은 시계 아이콘(전송 중)이 표시된다. 서버에 도달하면 체크 표시로 바뀐다.
- 목록 순서 변경: 사용자가 드래그 앤 드롭으로 할 일 목록의 순서를 바꾸면, 즉시 UI에 반영된다. 실제 데이터베이스 업데이트는 그 후에 일어난다.
이러한 예시들은 useOptimistic의 본질이 ‘UI를 미리 업데이트하는 것’에 있음을 분명히 했다. 그리고 그 ‘업데이트’의 형태는 무한했다. 숫자를 바꾸고, 목록에 아이템을 더하고, 객체의 속성을 변경하는 등, 서버의 확인이 필요한 거의 모든 종류의 상태 변화에 이 낙관적인 접근법을 적용할 수 있었다.
‘좋아요’ 버튼은 단지 시작일 뿐이었다. useOptimistic은 이제 React 개발자들이 사용자에게 즉각적인 피드백을 제공하는 모든 순간에 꺼내 들 수 있는, 강력하고 범용적인 도구로 자리매김했다. 문서는 이제 이 무한한 가능성을 개발자들에게 알려줄 준비를 마쳤다.


