본문으로 건너뛰기

데이터 뮤테이션

TanStack Router는 라우트 로더 데이터를 캐시하지만 뮤테이션 또는 제출 상태를 관리하지는 않습니다. 뮤테이션 워크플로에서 TanStack Router의 주요 역할은 로더 데이터를 무효화하고 외부 뮤테이션 이벤트로 인해 발생할 수 있는 URL 부작용에 대응하는 것입니다. 다음은 유용하게 사용할 수 있는 뮤테이션 관련 기능과 이를 구현하는 라이브러리 목록입니다.

다음 기능을 지원하는 뮤테이션 유틸리티를 찾아 사용합니다.

  • 제출 상태 처리 및 캐싱
  • 로컬 및 전역 낙관적 UI 지원
  • 무효화를 연결하는 기본 제공 훅(또는 무효화를 자동으로 지원)
  • 여러 진행 중인 뮤테이션 동시 처리
  • 전역에서 액세스할 수 있는 리소스로 뮤테이션 상태 구성
  • 제출 상태 이력 및 가비지 컬렉션

추천 라이브러리는 다음과 같습니다.

또는 다음 라이브러리도 있습니다.

데이터 가져오기와 마찬가지로 뮤테이션 상태에는 모든 경우에 맞는 단일 해법이 없으므로 필요와 팀의 요구에 맞는 해법을 선택해야 합니다. 몇 가지 다른 해법을 시도하여 가장 적합한 방식을 확인하는 것을 권장합니다.

⚠️ 아직 읽고 계신가요? 제출 상태는 지속성을 고려할 때 흥미로운 주제입니다. 모든 뮤테이션을 영원히 유지할까요? 언제 제거해야 하는지 어떻게 알 수 있을까요? 사용자가 화면을 떠났다가 다시 돌아오면 어떻게 될까요? 자세히 살펴보겠습니다!

뮤테이션 후 TanStack Router 무효화

TanStack Router에는 단기 캐싱이 기본 제공됩니다. 라우트 매치가 마운트 해제된 후에도 로더 데이터가 캐시된 상태로 남을 수 있으므로, 뮤테이션으로 활성 라우트 데이터와 캐시된 라우트 데이터가 모두 stale 상태가 될 수 있습니다.

로더 데이터와 관련된 뮤테이션이 발생하면 router.invalidate를 사용하여 커밋된 로더 세대, 캐시된 로더 세대, 진행 중인 로더 세대를 무효화할 수 있습니다. 일치하는 활성 프리로드 레인은 종료되고, 선택된 현재 활성 매치는 일반 로딩 프로토콜을 통해 다시 로드됩니다.

const router = useRouter()

const addTodo = async (todo: Todo) => {
try {
await api.addTodo()
router.invalidate()
} catch {
//
}
}

기본적으로 stale 상태인 성공한 로더 데이터는 백그라운드에서 재검증되므로 새 데이터를 사용할 수 있을 때까지 기존 데이터가 계속 표시됩니다. 캐시된 비활성 매치는 stale 상태로 유지되며 다시 사용될 때 다시 로드됩니다.

모든 로더가 완료될 때까지 무효화를 기다리려면 {sync: true}router.invalidate에 전달합니다.

const router = useRouter()

const addTodo = async (todo: Todo) => {
try {
await api.addTodo()
await router.invalidate({ sync: true })
} catch {
//
}
}

장기 뮤테이션 상태

사용하는 뮤테이션 라이브러리와 관계없이 뮤테이션은 제출과 관련된 상태를 만드는 경우가 많습니다. 대부분의 뮤테이션은 실행 후 잊어도 되지만, 일부 뮤테이션 상태는 낙관적 UI를 지원하거나 제출 상태에 대한 피드백을 사용자에게 제공하기 위해 더 오래 유지됩니다. 대부분의 상태 관리자는 이 제출 상태를 적절히 유지하고 노출하므로 로딩 스피너, 성공 메시지, 오류 메시지 등의 UI 요소를 표시할 수 있습니다.

다음 상호작용을 생각해 보겠습니다.

  • 사용자가 게시물을 편집하기 위해 /posts/123/edit 화면으로 이동합니다.
  • 사용자가 123 게시물을 편집하고 성공하면 편집기 아래에서 게시물이 업데이트되었다는 성공 메시지를 봅니다.
  • 사용자가 /posts 화면으로 이동합니다.
  • 사용자가 다시 /posts/123/edit 화면으로 이동합니다.

라우트 변경을 뮤테이션 관리 라이브러리에 알리지 않으면 제출 상태가 여전히 남아 사용자가 이전 화면으로 돌아왔을 때 **"게시물이 성공적으로 업데이트되었습니다"**라는 메시지를 계속 볼 수 있습니다. 이는 바람직하지 않습니다. 뮤테이션 상태를 영원히 유지하려던 것은 아니니까요!

뮤테이션 키 사용

가장 쉬운 방법은 뮤테이션 라이브러리가 키가 변경될 때 뮤테이션 상태를 재설정할 수 있는 키 메커니즘을 지원하도록 하는 것입니다.

const routeApi = getRouteApi('/room/$roomId/chat')

function ChatRoom() {
const { roomId } = routeApi.useParams()

const sendMessageMutation = useCoolMutation({
fn: sendMessage,
// Clear the mutation state when the roomId changes
// including any submission state
key: ['sendMessage', roomId],
})

// Fire off a bunch of messages
const test = () => {
sendMessageMutation.mutate({ roomId, message: 'Hello!' })
sendMessageMutation.mutate({ roomId, message: 'How are you?' })
sendMessageMutation.mutate({ roomId, message: 'Goodbye!' })
}

return (
<>
{sendMessageMutation.submissions.map((submission) => {
return (
<div>
<div>{submission.status}</div>
<div>{submission.message}</div>
</div>
)
})}
</>
)
}

router.subscribe 메서드 사용

사용 가능한 이벤트와 사용 시기를 자세히 알아보려면 라우터 이벤트 가이드를 참고합니다.

키 메커니즘이 없는 라이브러리에서는 사용자가 화면을 떠날 때 뮤테이션 상태를 수동으로 재설정해야 할 수 있습니다. 이를 해결하려면 사용자가 더 이상 뮤테이션 상태를 필요로 하지 않을 때 TanStack Router의 invalidatesubscribe 메서드를 사용하여 뮤테이션 상태를 지울 수 있습니다.

router.subscribe 메서드는 콜백을 다양한 라우터 이벤트에 구독하는 함수입니다. 여기서 사용할 이벤트는 onResolved 이벤트입니다. 이 이벤트는 위치 경로가 변경되고(단순히 다시 로드된 경우가 아님) 최종적으로 확인되었을 때 발생한다는 점을 이해해야 합니다.

이때 이전 뮤테이션 상태를 재설정하면 좋습니다. 예시는 다음과 같습니다.

const router = createRouter()
const coolMutationCache = createCoolMutationCache()

const unsubscribeFn = router.subscribe('onResolved', () => {
// Reset mutation states when the route changes
coolMutationCache.clear()
})