State snapshot, batching và immutable updates
Mỗi render nhìn một snapshot; setter yêu cầu render mới, không đổi biến state trong handler đang chạy.
1. Snapshot và update queue
Event handler capture state snapshot của render đã tạo nó. React enqueue update và batch trước render tiếp theo. Value update thay pending result; functional updater nhận kết quả trước trong queue, nên dùng khi next phụ thuộc previous hoặc có nhiều update.
setCount(count + 1); setCount(count + 1); // cùng snapshot
setCount(c => c + 1); setCount(c => c + 1); // compose queue
2. State model và ownership
Tránh redundant, duplicate và contradictory state. Lift state tới owner chung nhỏ nhất; không mirror props nếu không có semantics reset rõ. Dùng reducer/state machine hoặc discriminated union khi các trạng thái loại trừ nhau.
| Smell | Better model |
|---|---|
isLoading + error + data độc lập | Union idle/loading/success/error |
| Filtered list trong state | Derive từ items + filter |
| Hai component giữ cùng selection | Lift tới common owner |
| Prop copied once vào state | Controlled value hoặc intentional key/reset contract |
3. Object và array identity
State được xem read-only: tạo object/array mới cho changed path, không mutate alias. Shallow spread không clone nested graph; normalize state hoặc copy đúng path. Immer dùng proxy để produce immutable result nhưng vẫn cần hiểu identity và không leak draft.
4. Priority và responsive updates
Transitions đánh dấu non-urgent update có thể interrupt; controlled input urgent không đặt trong transition. Deferred value cho subtree chậm render với value lagging nhưng không thay debounce, request cancellation hoặc server cache.