Skip to main content

Product CRUD: Form Frontend đầy đủ state

CRUD form thường bị viết như một useState() lớn + fetch + tự map lỗi. Inertia useForm đã cung cấp hầu hết lifecycle state cần thiết.

Form data nên phù hợp với input trước

price để string ở UI vì <input> thực tế làm việc với text. Chuyển sang number ở boundary submit bằng transform().

Keyed useForm

Create:
Edit:
Key giúp Inertia nhớ form data/errors trong history state. Flow thực tế:
Key phải mang identity. EditProduct dùng chung cho mọi record sẽ tạo collision state.

Clear field error khi người dùng sửa lại

Server vẫn là authority; clear error chỉ là UX để lỗi cũ không bám trên field sau khi user đã thay input.

Submit có transform

Không cần tự fetch() và parse 422 JSON. Khi Laravel redirect validation errors, Inertia đưa lỗi về form.errors.

Loading state

Và disable cả fieldset:
Điều này ngăn double-submit và ngăn data thay đổi giữa lúc request đang chạy.

Error state

Đừng chỉ đổi border đỏ. Error cần readable text và nên có semantic accessibility.

Dirty state

Ứng dụng thật có thể dùng isDirty để:
  • disable submit khi chưa thay đổi;
  • cảnh báo trước khi đóng modal;
  • hiển thị unsaved badge;
  • quyết định có reset form hay không.

Cancel request

Cancel hữu ích cho upload/request dài. Với request lưu rất nhanh, nút cancel không phải lúc nào cũng cần hiển thị; sample giữ nó để minh họa lifecycle.

Success state cục bộ

Nếu submit redirect về index, flash message thường hữu ích hơn. Nếu save tại chỗ, recentlySuccessful cho feedback rất tự nhiên.

Create và Edit dùng cùng component

ProductForm chỉ sở hữu presentation/interaction. Page create/edit sở hữu endpoint và intent submit. Đây là separation tốt hơn việc component form tự đoán đang create hay edit qua nullable ID.

Upload ảnh và progress

Phần image lifecycle được tách riêng để không làm form cơ bản quá tải. Đọc tiếp Product CRUD: upload ảnh, preview và progress.

Full source

Khi nào dùng <Form> thay useForm?

Dùng <Form> khi bạn muốn declarative form gần với HTML form và ít imperative logic. Dùng useForm khi:
  • form có derived interaction;
  • cần programmatic setData;
  • cần nhiều button/intent;
  • cần transform theo state runtime;
  • cần truy cập lifecycle state ở nhiều component.
Reference CRUD chọn useForm vì mục tiêu là trình diễn đầy đủ state machine của form.

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.