Part 07 · Deep Dive · 7.3A
React execution labs
Bốn bài thực thi tập trung vào cách tạo bằng chứng: controlled async race, identity test, Profiler measurement, external-store consistency và accessibility journey.
Execution rule: giữ một commit hoặc fixture tái hiện lỗi trước khi sửa. Mỗi kết luận phải đi kèm test, trace, log hoặc accessibility evidence có thể chạy lại.
Lab A · Effect race và Strict Mode
Tạo màn hình user detail đổi nhanh theo userId. Controlled promises cho phép A trả chậm hơn B để lỗi stale overwrite xảy ra chắc chắn.
useEffect(() => {
const controller = new AbortController();
let ignore = false;
loadUser(userId, controller.signal)
.then(user => { if (!ignore) setUser(user); })
.catch(error => {
if (error.name !== 'AbortError' && !ignore) setError(error);
});
return () => {
ignore = true;
controller.abort();
};
}, [userId]);
- Mock response A chậm, B nhanh; trước fix, assert A overwrite B.
- Bật Strict Mode, log setup/cleanup và kiểm resource lifecycle đối xứng.
- Unmount khi request pending; assert abort và không update stale state.
- Chạy exhaustive-deps; restructure thay vì suppress stale closure.
Done khi: test race deterministic; active user luôn khớp URL/prop; abort signal được quan sát; setup-cleanup-setup không leak hoặc duplicate subscription.
Lab B · State identity và keys
Dùng editable list có input, expanded state và focus để chứng minh identity bug trực quan lẫn bằng test.
- Render list bằng index key, sửa draft của một row rồi reorder; assert draft bám nhầm entity.
- Đổi sang stable domain ID; test insert, delete và reorder không mất identity.
- Mutate object/array tại chỗ để tái hiện snapshot/memo sai, rồi sửa immutable update đúng path.
- Chuyển state transition nhiều nhánh sang reducer; test invalid action và invariant.
Done khi: test fail trên index/mutation version và pass trên stable/immutable version; focus/draft theo đúng ID; reducer không tạo impossible state.
Lab C · Profiler và external state
Render 5.000 rows dưới một Context cập nhật thường xuyên và thêm một external store subscription. Lưu baseline trước mọi optimization.
- Record commit duration, render count và browser long task cho một interaction cụ thể.
- Tách Context theo responsibility/frequency hoặc dùng selector phù hợp.
- Thêm memoization chỉ ở subtree Profiler chứng minh đắt; dùng virtualization nếu DOM size là root cause.
- Với external store, test cached snapshot, unsubscribe, server snapshot và consistency giữa nhiều subscriber.
Done khi: có Profile export hoặc screenshot kèm số liệu trước–sau; interaction correctness giữ nguyên; no tearing trong test/transition; keyboard navigation vẫn hoạt động với virtualization.
Lab D · Accessibility journey
Xây flow tạo order gồm form, validation summary, confirmation modal và async save status. Không bắt đầu bằng ARIA nếu native element đã có semantics đúng.
- Gắn label, hint/error association; sau submit lỗi, focus summary hoặc field theo UX contract.
- Modal nhận focus ban đầu, giữ focus trong vùng hợp lệ, đóng bằng Escape và trả focus trigger.
- Background không tương tác khi modal mở; save status được announce đúng mức live region.
- Test keyboard-only, accessible name/role/state, contrast, zoom/reflow và reduced motion.
Done khi: Testing Library assertions dùng role/name; browser accessibility tree đúng; manual keyboard checklist đạt; screen reader critical announcements được ghi nhận.
Deliverables bắt buộc
- Race test dùng controlled promises, không dùng sleep may rủi.
- Strict Mode setup/cleanup log hoặc assertion.
- Identity test bao phủ insert/delete/reorder và row-local state.
- Profiler export hoặc before/after metrics với cùng workload.
- External-store snapshot/subscription/SSR tests.
- Testing Library assertions theo role/name, không implementation detail.
- Keyboard, focus và screen-reader verification notes.
- README nêu root cause, trade-off và cách chạy lại evidence.