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]);
  1. Mock response A chậm, B nhanh; trước fix, assert A overwrite B.
  2. Bật Strict Mode, log setup/cleanup và kiểm resource lifecycle đối xứng.
  3. Unmount khi request pending; assert abort và không update stale state.
  4. 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.

  1. Render list bằng index key, sửa draft của một row rồi reorder; assert draft bám nhầm entity.
  2. Đổi sang stable domain ID; test insert, delete và reorder không mất identity.
  3. Mutate object/array tại chỗ để tái hiện snapshot/memo sai, rồi sửa immutable update đúng path.
  4. 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.

  1. Record commit duration, render count và browser long task cho một interaction cụ thể.
  2. Tách Context theo responsibility/frequency hoặc dùng selector phù hợp.
  3. Thêm memoization chỉ ở subtree Profiler chứng minh đắt; dùng virtualization nếu DOM size là root cause.
  4. 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.

  1. Gắn label, hint/error association; sau submit lỗi, focus summary hoặc field theo UX contract.
  2. Modal nhận focus ban đầu, giữ focus trong vùng hợp lệ, đóng bằng Escape và trả focus trigger.
  3. Background không tương tác khi modal mở; save status được announce đúng mức live region.
  4. 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