Component vs FlowModel
Trong phát triển Plugin NocoBase, viết UI frontend có hai cách: component React thông thường và FlowModel. Hai cái không phải là quan hệ thay thế lẫn nhau — FlowModel là một lớp bọc trên component React, thêm khả năng cấu hình trực quan cho component.
Thông thường, bạn không cần đắn đo quá lâu. Hãy tự hỏi mình một câu hỏi:
Component này có cần xuất hiện trong menu "Thêm Block / Field / Action" của NocoBase, để người dùng cấu hình trực quan trên giao diện không?
- Không cần → Dùng component React thông thường, là phát triển React tiêu chuẩn
- Cần → Dùng FlowModel để bọc
Phương án mặc định: Component React
Phần lớn ngữ cảnh Plugin dùng component React thông thường là đủ. Ví dụ:
- Đăng ký một trang độc lập (trang cài đặt plugin, trang route tùy chỉnh)
- Viết một dialog, form, list, v.v. làm component nội bộ
- Đóng gói một component UI loại tiện ích
Trong các ngữ cảnh này, viết component bằng React + Antd, lấy năng lực context của NocoBase (gửi request, i18n, v.v.) thông qua useFlowContext(), không khác gì phát triển frontend thông thường.
Cách dùng chi tiết xem tại Phát triển Component.
Khi nào dùng FlowModel
Khi component của bạn cần đáp ứng các điều kiện sau, dùng FlowModel:
- Xuất hiện trong menu: Cần để người dùng thêm thông qua menu "Thêm Block", "Thêm Field", "Thêm Action"
- Hỗ trợ cấu hình trực quan: Người dùng có thể click vào các mục cấu hình trên giao diện để chỉnh sửa thuộc tính của component (ví dụ chỉnh tiêu đề, chuyển chế độ hiển thị)
- Cấu hình cần được lưu trữ: Cấu hình của người dùng cần được lưu lại, khi mở trang lần sau vẫn còn
Nói đơn giản, FlowModel giải quyết vấn đề "làm cho component có thể cấu hình, có thể lưu trữ". Nếu component của bạn không cần các năng lực này, không cần dùng nó.
Mối quan hệ giữa hai cái
FlowModel không dùng để "thay thế" component React. Nó là một lớp trừu tượng trên component React:
Trong phương thức render() của một FlowModel, viết chính là code React thông thường. Sự khác biệt là: props của component thông thường là cố định hoặc được truyền từ component cha vào, còn props của FlowModel được sinh ra động thông qua Flow (quy trình cấu hình).
Thực tế, hai cái có cấu trúc cơ bản khá tương đồng:
Tuy nhiên cách quản lý của chúng hoàn toàn khác nhau. Component React dựa vào lồng JSX để tạo thành cây component — đây là cây render UI khi runtime. Còn FlowModel được FlowEngine quản lý, tạo thành cây model — một cây cấu trúc logic có thể lưu trữ, có thể đăng ký động, kiểm soát quan hệ cha-con tường minh thông qua setSubModel / addSubModel, phù hợp để xây dựng các cấu trúc cần quản lý cấu hình hóa như Block trang, luồng thao tác, model dữ liệu.
So sánh năng lực
Nh ìn từ góc độ kỹ thuật hơn về sự khác biệt giữa hai cái:
Nếu bạn quen thuộc với vòng đời React, vòng đời của FlowModel rất dễ map qua — onInit tương ứng constructor, onMount tương ứng componentDidMount, onUnmount tương ứng componentWillUnmount.
Ngoài ra, FlowModel còn cung cấp một số năng lực mà component React không có:
registerFlow— Đăng ký Flow, định nghĩa quy trình cấu hìnhapplyFlow/dispatchEvent— Thực thi hoặc kích hoạt FlowopenFlowSettings— Mở bảng cài đặt của bước Flowsave/saveStepParams()— Lưu trữ cấu hình modelcreateFork— Một logic model được tái sử dụng render nhiều lần (ví dụ mỗi hàng của bảng)
Các năng lực này là nền tảng hỗ trợ trải nghiệm "cấu hình trực quan". Nếu ngữ cảnh của bạn không liên quan đến cấu hình trực quan, không cần quan tâm đến chúng. Cách dùng chi tiết xem tại Tài liệu FlowEngine đầy đủ.
Đối chiếu ngữ cảnh
Áp dụng từng bước
Khi không chắc chắn, trước tiên dùng component React để triển khai chức năng. Sau khi xác nhận cần năng lực cấu hình trực quan, dùng FlowModel để bọc — đây là cách làm tiệm tiến được khuyến nghị. Nội dung khối lớn dùng FlowModel để quản lý, chi tiết bên trong dùng component React để triển khai, hai cái phối hợp với nhau.
Liên kết liên quan
- Phát triển Component — Cách viết component React và cách dùng useFlowContext
- Tổng quan FlowEngine — Cách dùng cơ bản FlowModel và registerFlow
- Tài liệu FlowEngine đầy đủ — Tham chiếu đầy đủ FlowModel, Flow, Context

