← Về danh sách bài họcBài 14/25
⏳ Bài 14: useTransition & useDeferredValue
🎯 Sau bài học này, bạn sẽ:
- Hiểu Concurrent Features trong React 18
- Dùng useTransition để ưu tiên cập nhật UI
- Dùng useDeferredValue cho giá trị "trì hoãn"
- Xây dựng search với UX mượt mà
1. useTransition
useTransition cho phép đánh dấu một state update là "không khẩn cấp", giúp React ưu tiên cập nhật UI khẩn cấp trước.
import { useState, useTransition } from 'react';
function SearchPage() {
const [query, setQuery] = useState('');
const [results, setResults] = useState([]);
const [isPending, startTransition] = useTransition();
const handleSearch = (e) => {
const value = e.target.value;
// Cập nhật input NGAY LẬP TỨC (khẩn cấp)
setQuery(value);
// Cập nhật results TRỄ hơn (không khẩn cấp)
startTransition(() => {
const filtered = heavySearch(value); // Tính toán nặng
setResults(filtered);
});
};
return (
<div>
<input value={query} onChange={handleSearch} placeholder="Tìm kiếm..." />
{isPending && <p>Đang tìm...</p>}
<ul>
{results.map(r => <li key={r.id}>{r.name}</li>)}
</ul>
</div>
);
}💡 Khi nào dùng: Khi bạn có 2 state updates, 1 cần phản hồi ngay (input, button) và 1 có thể chờ (filter list, render chart).
2. useDeferredValue
useDeferredValue trì hoãn cập nhật một giá trị cho đến khi React rảnh:
import { useState, useDeferredValue, useMemo } from 'react';
function FilteredList({ items }) {
const [filter, setFilter] = useState('');
const deferredFilter = useDeferredValue(filter);
// useMemo + deferredValue: list cập nhật trễ, input mượt
const filteredItems = useMemo(() => {
return items.filter(item =>
item.name.toLowerCase().includes(deferredFilter.toLowerCase())
);
}, [items, deferredFilter]);
const isStale = filter !== deferredFilter;
return (
<div>
<input
value={filter}
onChange={e => setFilter(e.target.value)}
placeholder="Filter..."
/>
<div style={{ opacity: isStale ? 0.5 : 1 }}>
{filteredItems.map(item => (
<div key={item.id}>{item.name}</div>
))}
</div>
</div>
);
}3. useTransition vs useDeferredValue
| Tiêu chí | useTransition | useDeferredValue |
|---|---|---|
| Wrap | State update (setter) | Giá trị (value) |
| Khi nào | Bạn kiểm soát setState | Nhận value từ props/parent |
| isPending | Có | So sánh value vs deferred |
📝 Tóm Tắt
useTransition: wrap setState không khẩn cấp, có isPendinguseDeferredValue: trì hoãn value, dùng khi nhận từ props- Cả hai giúp UI mượt khi có tính toán nặng