Request lifecycle, debounce và race condition
Search-as-you-type là nơi dễ phát sinh request chồng nhau nhất. Mục tiêu không phải “không bao giờ có request song song”, mà là UI cuối cùng phải phản ánh intent mới nhất của user.Pattern an toàn
Mutation khác search
Với mutation, ưu tiên disable action trongprocessing. Double-click hai lần vào “Thanh toán”, “Đặt chỗ” hoặc “Tạo đơn” không nên dựa vào frontend để đảm bảo uniqueness; backend vẫn cần idempotency/unique constraint/transaction phù hợp với domain.
Cancel không đồng nghĩa rollback
Nếu client cancel request sau khi server đã commit DB, cancel chỉ có thể ngừng phía client chờ response; nó không tự hoàn tác side effect ở server. Vì vậy những action có side effect quan trọng phải có transaction/business invariant ở backend.Tách state
searchDraft: local state, thay đổi từng keypress.filters: server props/URL, state đã commit vào navigation.users: server state.isFilterPanelOpen: local UI state.
Request lifecycle đầy đủ để debug
Một visit thực tế nên được nhìn như state machine:onFinish phải là nơi cleanup vì nó chạy cho cả success và failure path.
Search race: debounce chưa phải toàn bộ câu chuyện
fetch không có owner.