Cơ chế hoạt động và kiến trúc của React-Awesome-Query-Builder

React-Awesome-Query-Builder là một thư viện mã nguồn mở cho phép xây dựng giao diện truy vấn trực quan trong ứng dụng React. Thiết kế kiến trúc của nó tập trung vào tính mô-đun, khả năng mở rộng và tách biệt rõ ràng giữa logic nghiệp vụ và giao diện người dùng.

Kiến trúc đa gói (Monorepo)

Dự án được tổ chức theo mô hình monorepo với các gói con nằm trong thư mục packages/:

  • core: Xử lý logic truy vấn, chuyển đổi dữ liệu và quản lý cấu hình
  • ui: Cung cấp các thành phần giao diện cơ bản
  • ui/widgets: Triển khai các widget tương tác như dropdown, input, toggle
  • các theme: Bao gồm antd, material, bootstrap để tùy chỉnh giao diện

Sự phân tách này giúp mỗi lớp đảm nhiệm một trách nhiệm duy nhất, dễ kiểm thử và bảo trì.

Xử lý dữ liệu và quản lý trạng thái

Lớp core định nghĩa cấu trúc cây (query tree) để biểu diễn điều kiện truy vấn. Mỗi nút trong cây có thể là:

  • Group: Nhóm các điều kiện con với toán tử AND/OR
  • Rule: Một điều kiện đơn lẻ gồm trường, toán tử và giá trị

Trạng thái cây được lưu trữ và cập nhật thông qua TreeStore, sử dụng immutable data structure để đảm bảo tính toàn vẹn khi thay đổi.

// Ví dụ về cấu trúc cây truy vấn
{
  id: 'g1',
  type: 'group',
  children: [
    {
      id: 'r1',
      type: 'rule',
      field: 'age',
      operator: 'greater_than',
      value: 18
    }
  ],
  conjunction: 'AND'
}

Giao tiếp giữa các thành phần

Luồng dữ liệu tuân theo nguyên tắc một chiều:

  1. Người dùng tương tác với UI (thêm điều kiện, đổi toán tử...)
  2. Gọi hàm từ đối tượng actions (được inject qua props)
  3. TreeStore tạo bản sao mới của cây với thay đổi tương ứng
  4. Component gốc nhận lại cây mới qua props và re-render đệ quy

Component Builder đóng vai trò gốc, nhận vào tree, configactions, sau đó render đệ quy các Item dựa trên loại nút:

const QueryItem = ({ node, path, config, actions }) => {
  if (node.type === 'group') {
    return <GroupNode node={node} path={path} config={config} actions={actions} />;
  }
  return <RuleNode node={node} path={path} config={config} actions={actions} />;
};

Tùy biến giao diện qua hệ thống theme

Mỗi theme (ví dụ antd) cung cấp triển khai riêng cho các widget như:

  • FieldSelect: Chọn trường dữ liệu
  • OperatorSelect: Chọn toán tử so sánh
  • ValueEditor: Nhập giá trị (text, number, date...)

Việc thay theme chỉ cần import đúng bộ UI và truyền vào cấu hình, không ảnh hưởng đến logic core.

Nguyên tắc thiết kế đáng học hỏi

  • Tách biệt rõ ràng: Core không phụ thuộc UI, UI không chứa logic nghiệp vụ
  • Cấu hình linh hoạt: Hành vi component được điều khiển hoàn toàn qua đối tượng config
  • Immutable state: Mọi thay đổi tạo ra bản sao mới, tránh side effect
  • Extensible API: Dễ dàng mở rộng toán tử, kiểu dữ liệu hoặc widget mới

Thẻ: react query-builder component-architecture monorepo immutable-state

Đăng vào ngày 21 tháng 5 lúc 18:47