Tips & tricks Inertia.js khi đi làm
Bài này không phải danh sách API. Mục tiêu là trả lời câu hỏi khó hơn: khi nào nên dùng capability nào của Inertia, vì sao, và lỗi production thường xuất hiện ở đâu.Baseline của các sample: Inertia.js v3 + Laravel + React + TypeScript. Tên API nên luôn đối chiếu lại tài liệu v3 trước khi áp dụng vào project đang dùng version khác.
1. Giữ tư duy server-driven trước khi thêm client architecture
Anti-pattern phổ biến nhất là dùng Inertia nhưng vẫn dựng lại REST SPA đầy đủ:2. Server props là snapshot, không phải store bất tử
Một prop nhận từ server mô tả state tại thời điểm page response được tạo. Đừng mirror vô điều kiện:props.products có thể mới nhưng local copy vẫn cũ.
Tốt hơn:
3. Search/filter: tách draft state và committed URL state
Đây là pattern rất hữu ích:replace: true? Nếu mỗi ký tự tạo một history entry thì Back button trở thành chuỗi t -> tu -> tua -> tuan.
4. Partial reload chỉ nhanh khi server prop cũng lazy
Client:only: ['products'] không tự động làm một query đã chạy trước khi Inertia::render() biến mất.
5. Đừng gửi shared props như một global state dump
Tốt:6. Form state: dùng useForm thay vì tự dựng loading/error plumbing
CreateProduct giúp form có history identity rõ hơn. Với edit:
7. Nhiều form cùng page: tránh validation collision
Nếu không dùng form helper hoặc có manual visit, hai form có cùng fieldname dễ đụng errors.
8. Validation Inertia là redirect flow, không phải JSON 422 flow
Đừng viết theo thói quen axios:9. Loading phải đúng scope
Một progress bar global không thay thế loading của button.10. preserveState và preserveScroll không nên bật theo phản xạ
Search/filter thường cần:
11. Scroll container riêng phải khai báo scroll region
Nếu layout dùng container scroll thay vì body:12. Prefetch: tối ưu latency, không phải miễn phí
13. Deferred props: tách critical path khỏi secondary data
Server:14. Optimistic update phải có reconciliation plan
Toggle status là candidate tốt:15. Race condition: search request cũ không được thắng request mới
Search debounce giảm request nhưng không loại bỏ mọi race. Khi interaction có thể spam request, hãy tận dụng lifecycle/cancel semantics phù hợp của router thay vì tự tạo nhiềufetch không quản lý.
Một pattern UI đơn giản:
16. Dùng useHttp khi request không phải page visit
Inertia v3 có useHttp cho HTTP request độc lập. Ví dụ autocomplete gọi external/internal JSON endpoint không cần thay page:
useHttp để tái tạo API layer cho mọi CRUD nếu redirect + props đã giải quyết tốt.
17. Flash là notification, không phải canonical state
Backend:flash.product như nguồn dữ liệu thay cho prop product/DB.
18. External redirect nên để server phát lệnh rõ ràng
Ví dụ redirect sang cổng thanh toán hoặc external SSO:window.location nếu redirect là kết quả nghiệp vụ của request server.
19. Instrument router events để debug production
Có thể gắn instrumentation ở bootstrap/layout:20. Dev error modal không phải production error UX
Local development có thể thấy non-Inertia response trong modal rất tiện. Production cần error page Inertia chuẩn:21. Asset version mismatch là một phần của deployment flow
Sau deploy frontend asset mới, tab cũ có thể đang giữ page version cũ. Inertia có asset versioning để buộc full-page refresh khi version không còn khớp. Practical implication:22. Authorization: UI hint khác security boundary
Frontend:23. Đừng gửi Eloquent model thô nếu page contract quan trọng
Tốt hơn dùng resource/DTO shape rõ:24. N+1 vẫn là N+1 dù dùng Inertia
25. Một request có nhiều concern: dùng prop boundary để tối ưu
Page dashboard:26. Checklist trước khi thêm global client store
Hỏi lần lượt:- State này có canonical source ở DB/backend không?
- Nó có thể biểu diễn bằng URL không?
- Nó chỉ sống trong một form không?
- Nó chỉ là UI transient không?
- Nó có cần sống qua Back/Forward không?
- Inertia props/useForm/useRemember đã giải quyết chưa?
27. Debugging playbook
Khi một interaction “không chạy đúng”, trace theo lớp:28. Production checklist ngắn
Trước khi merge một feature Inertia, tự hỏi:Kết luận
Inertia mạnh nhất khi bạn không cố biến nó thành một SPA architecture khác. Giữ business state ở server, navigation state ở URL, form state trong form helper, local state cho UI thật sự local; sau đó dùng partial reload, deferred, prefetch và optimistic update như các công cụ có semantics rõ ràng thay vì “bật cho nhanh”.29. Modal form/upload: cân nhắc cancelOnUnmount
Một form nằm trong modal có thể bị unmount trong khi request vẫn đang chạy. Nếu user đóng modal mà bạn không muốn upload/submit tiếp tục, Inertia v3 <Form> hỗ trợ cancelOnUnmount:
30. Real-time validation: ưu tiên Precognition thay vì duplicate rule ở client
Nếu product SKU cần validate trước submit, Inertia v3 có tích hợp Precognition:31. Phân biệt httpException và networkError
Inertia v3 có event riêng cho non-Inertia HTTP response và lỗi mạng bất ngờ:
32. Prefetch cache có freshness và stale budget riêng
Inertia v3 cho phép cấu hìnhcacheFor, kể cả fresh/stale duration dạng mảng. Đừng coi prefetch cache như dữ liệu sống mãi.
33. Cache invalidation phải đi cùng mutation semantics
Form v3 có option invalidate cache tags. Nếu app dùng prefetch cache/tag strategy, mutation nên nói rõ cache nào không còn đáng tin:34. withAllErrors() chỉ dùng khi UX thực sự cần nhiều message/field
Mặc định một error đầu tiên mỗi field thường dễ đọc hơn. Nếu product rule cần show toàn bộ lỗi:
errors.sku có thể là array. Đừng bật chỉ vì “nhiều thông tin hơn” rồi làm UI quá tải.