Cả hai đánh dấu một cập nhật là non-urgent để React được phép gián đoạn, ưu tiên input của người dùng. Khác nhau ở chỗ bạn nắm được gì.
useTransition — bạn kiểm soát hành động cập nhật state. Bọc setState trong startTransition để nó thành low-priority; nhận lại cờ isPending để hiện trạng thái loading.
const [isPending, startTransition] = useTransition()
startTransition(() => setQuery(value)) // update này nhường chỗ cho gõ phímDùng khi bạn sở hữu setter (đổi tab, lọc list ngay trong component, navigation).
useDeferredValue — bạn chỉ có một value (từ props hay state người khác quản), không gọi được setState của nó. Tạo bản "trễ" của value đó:
const deferredQuery = useDeferredValue(query)
// render list nặng theo deferredQuery; input vẫn cập nhật ngay theo queryDùng khi value đến từ trên xuống (prop), hoặc khi defer một phần render nặng dựa trên giá trị có sẵn.
Quy tắc nhanh: kiểm soát được setState → useTransition. Chỉ có value, không có setter → useDeferredValue. Cả hai không làm code chạy nhanh hơn, chỉ giúp giữ UI phản hồi bằng cách hoãn phần nặng.
Both mark an update as non-urgent so React may interrupt it and prioritize user input. They differ in what you have a handle on.
useTransition — you control the state update action. Wrap setState in startTransition to make it low-priority; you get back an isPending flag for a loading state.
const [isPending, startTransition] = useTransition()
startTransition(() => setQuery(value)) // this update yields to typingUse when you own the setter (tab switch, filtering a list in-component, navigation).
useDeferredValue — you only have a value (from props or someone else's state) and can't call its setter. Create a "lagging" copy of it:
const deferredQuery = useDeferredValue(query)
// render the heavy list off deferredQuery; the input still updates instantly off queryUse when the value comes from above (a prop), or to defer part of a heavy render off an existing value.
Quick rule: you control the setState → useTransition. You only have a value, no setter → useDeferredValue. Neither makes code faster — they keep the UI responsive by deferring the heavy part.