Product CRUD: Index Frontend chuyên sâu
Đây là page thể hiện nhiều sức mạnh Inertia nhất trong sample.
Types
resources/js/types/product.ts
Search: local typing state, server owns canonical filter
Đây là chỗ nhiều app làm sai. Nếu mỗi ký tự gọi request ngay thì request density quá cao; nếu chỉ giữ search local thì URL không share/bookmark được.
Giải pháp:
Ý nghĩa từng option:
only: không request lại prop không liên quan như stats.
preserveState: input đang focus và local interaction không bị reset.
preserveScroll: bảng không nhảy lên đầu trang.
replace: gõ i → ip → iph → iphone không tạo bốn history entry.
page: 1: filter mới luôn quay về page hợp lệ.
preserveState không có nghĩa filter nên nằm local. URL/server vẫn là source of truth; local search chỉ là buffer trong khoảng debounce.
Filter/sort dùng cùng một visit function
Điều này giữ contract nhất quán giữa search/status/sort.
Deferred stats
Backend:
React:
Mental model:
Deferred không phải “lazy load mọi thứ”. Nếu dữ liệu quyết định layout chính hoặc quyền truy cập, đừng defer tùy tiện.
Prefetch create/edit
Prefetch phù hợp vì hover vào nút edit/create có xác suất cao dẫn tới click thật. Không nên prefetch hàng trăm row ngay khi mount.
Optimistic toggle
Toggle active/inactive là use case optimistic tốt vì:
- thay đổi nhỏ;
- deterministic;
- dễ rollback;
- user mong phản hồi tức thì.
Runtime:
Đừng optimistic một thao tác mà user không thể hiểu trạng thái rollback, ví dụ payment hoặc mutation nhiều aggregate.
Delete: cố tình không optimistic
Lý do: delete có tính phá hủy. Feedback hơi chậm nhưng predictable thường tốt hơn “biến mất rồi xuất hiện lại” khi server reject.
withQueryString() phía Laravel giữ filter trong pagination URL, nên reload/share URL vẫn đúng.
Full Index source
File hoàn chỉnh nằm tại:
Nên đọc source đó sau khi hiểu từng khối trên. Giá trị của sample nằm ở cách các capability phối hợp, không phải ở một option riêng lẻ.
Tài liệu chính thức
Nội dung thực chiến trong bài được xây dựng dựa trên API và nguyên lý của Inertia.js v3 Documentation. Khi áp dụng vào dự án, hãy đối chiếu API cụ thể với tài liệu chính thức theo phiên bản bạn đang sử dụng.