Đây là stale response — nhiều request cùng bay, thứ tự phản hồi không đảm bảo theo thứ tự gửi. Request cho "ipho" có thể về sau request cho "iphone" và ghi đè state.
Ba cách xử lý, xếp theo mức độ nên dùng:
1. Huỷ request cũ (tốt nhất) — tiết kiệm cả băng thông:
js
let controller
async function search(term) {
controller?.abort()
controller = new AbortController()
try {
const res = await fetch(url(term), { signal: controller.signal })
setResults(await res.json())
} catch (err) {
if (err.name !== 'AbortError') throw err
}
}**2.
Bỏ qua phản hồi lỗi thời** khi không huỷ được (vd query chạy trên nhiều nguồn):
js
let latestId = 0
async function search(term) {
const id = ++latestId
const data = await fetchResults(term)
if (id !== latestId) return // đã có request mới hơn, bỏ kết quả này
setResults(data)
}3. Debounce đầu vào (300ms) để giảm số request — nhưng debounce không loại bỏ được race, chỉ làm nó hiếm hơn. Vẫn phải có (1) hoặc (2).
Trong React, thêm cleanup của useEffect gọi controller.abort() để huỷ khi phụ thuộc đổi hoặc component unmount. Thư viện data-fetching (TanStack Query, SWR) đã xử lý sẵn phần này qua query key.