React JSONSchema Form:構建強大且靈活的動態表單

作者: Calpa Liu
字數:1333
出版:2025 年 3 月 20 日
在當今的 Web 開發中,表單是與用戶交互的最重要界面之一。對於 React 開發者來說,有多種表單解決方案可供選擇,其中 React JSONSchema Form (RJSF) 以其獨特的方式脫穎而出。本文將深入探討這個強大的表單庫,了解如何利用它構建複雜表單,以及如何通過自定義組件提升用戶體驗。

React JSONSchema Form 是一個能夠基於 JSON Schema 自動生成 HTML 表單的 React 組件。它的核心理念是:只需提供一個 JSON Schema 描述數據結構,就能自動生成對應的表單界面。這種方法特別適合處理動態生成的表單,或者基於後端 API 響應構建表單的場景。

React JSONSchema Form
React JSONSchema Form

import Form from "@rjsf/core";
import validator from "@rjsf/validator-ajv8";

const schema = {
  title: "Todo",
  type: "object",
  required: ["title"],
  properties: {
    title: { type: "string", title: "Title", default: "A new task" },
    done: { type: "boolean", title: "Done?", default: false },
  },
};

const log = (type) => console.log.bind(console, type);

const TodoForm = () => (
  <Form
    schema={schema}
    validator={validator}
    onChange={log("changed")}
    onSubmit={log("submitted")}
    onError={log("errors")}
  />
);

構建複雜表單的關鍵技術

JSON Schema
JSON Schema

1. JSON Schema 定義數據結構

使用 React JSONSchema Form 的第一步是定義 JSON Schema,它描述了表單的數據結構、類型和約束。JSON Schema 不僅可以定義基本的數據類型(如字符串、數字、布爾值),還可以處理複雜的嵌套對象和數組。

例如,以下 Schema 定義了一個包含地址和個人信息的複雜表單:

{
  "type": "object",
  "properties": {
    "house_address": {
      "type": "object",
      "properties": {
        "street": { "type": "string" },
        "city": { "type": "string" }
      }
    },
    "firstName": { "type": "string" },
    "lastName": { "type": "string" },
    "age": { "type": "number" },
    "telephone": { "type": "string" }
  }
}

2. 利用 uiSchema 自定義界面

雖然 JSON Schema 定義了數據結構,但 uiSchema 則允許開發者自定義表單的外觀和行為。通過 uiSchema,你可以:

  • 重新排序表單字段
  • 應用自定義 widgets 和 fields
  • 添加 CSS 類名
  • 設置自動聚焦、佔位符等 UI 特性
const uiSchema = {
  "ui:order": ["firstName", "lastName", "age", "house_address", "telephone"],
  firstName: {
    "ui:autofocus": true,
    "ui:placeholder": "請輸入名字",
  },
  age: {
    "ui:widget": "updown",
  },
};

3. 表單驗證

React JSONSchema Form 基於 JSON Schema 自動處理表單驗證。你可以在 Schema 中使用 required 屬性標記必填字段,或使用各種驗證關鍵字(如 minimummaximumpattern 等)定義更複雜的驗證規則。

與其他表單構建庫的比較

React JSONSchema Form 與其他流行的表單庫(如 Formik、React Hook Form 和 React Final Form)有著明顯的區別:

聲明式 vs 命令式

RJSF 采用聲明式方法,通過 JSON Schema 描述表單結構,而其他庫通常需要開發者手動編寫每個表單字段。這使得 RJSF 特別適合處理動態表單或從 API 生成的表單。

自動驗證

RJSF 基於 JSON Schema 自動處理表單驗證,而其他庫通常需要開發者編寫自定義驗證邏輯。

性能考量

React Hook Form 專注於最小化重新渲染,因此在非常大的表單中性能可能優於 RJSF。不過,RJSF 對於中小型表單提供了良好的性能和易用性平衡。

使用場景

  • RJSF:最適合動態生成的表單或基於 API 響應的表單
  • React Hook Form/Formik:更適合完全自定義的表單,對每個字段的行為都需要精確控制

自定義組件:提升表單界面

Customization
Customization

RJSF 真正的強大之處在於其可擴展性,允許開發者完全自定義表單的外觀和行為。

自定義 Widgets

Widgets 表示用戶輸入數據的 HTML 標籤,如 inputselect 等。通過自定義 widgets,你可以替換默認的輸入元素:

const CustomCheckbox = function (props) {
  return (
    <button
      id="custom"
      className={props.value ? "checked" : "unchecked"}
      onClick={() => props.onChange(!props.value)}
    >
      {String(props.value)}
    </button>
  );
};

const widgets = {
  CheckboxWidget: CustomCheckbox,
};

<Form schema={schema} uiSchema={uiSchema} widgets={widgets} />;

自定義 Fields

Fields 控制整個表單字段的渲染,包括標籤、幫助文本和輸入元素。自定義 fields 可以完全重寫字段的呈現方式:

class GeoPosition extends React.Component {
  constructor(props) {
    super(props);
    this.state = { ...props.formData };
  }

  onChange(name) {
    return (event) => {
      this.setState(
        {
          [name]: parseFloat(event.target.value),
        },
        () => this.props.onChange(this.state)
      );
    };
  }

  render() {
    const { lat, lon } = this.state;
    return (
      <div className="geo-position-input">
        <input type="number" value={lat} onChange={this.onChange("lat")} />
        <input type="number" value={lon} onChange={this.onChange("lon")} />
      </div>
    );
  }
}

const uiSchema = { "ui:field": "geo" };
const fields = { geo: GeoPosition };

<Form schema={schema} uiSchema={uiSchema} fields={fields} />;

自定義模板

模板允許你重構表單的整體布局。例如,使用 FieldTemplate 自定義每個表單行的布局:

function CustomFieldTemplate(props) {
  const {
    id,
    classNames,
    label,
    help,
    required,
    description,
    errors,
    children,
  } = props;
  return (
    <div className={classNames}>
      <label htmlFor={id}>
        {label}
        {required ? "*" : null}
      </label>
      {description}
      <div className="custom-field-container">{children}</div>
      {errors}
      {help}
    </div>
  );
}

<Form schema={schema} FieldTemplate={CustomFieldTemplate} />;

實際應用案例

React JSONSchema Form 特別適合以下場景:

  1. 動態表單:根據用戶選擇或 API 響應動態調整表單結構
  2. 管理界面:通過 JSON Schema 快速生成 CRUD 操作界面
  3. 複雜的多步驟表單:結合自定義模板創建分步驟表單體驗
  4. 基於配置的表單系統:允許非技術人員通過配置定義表單

使用技巧與最佳實踐

  1. 分解複雜表單:對於非常複雜的表單,考慮將其分解為多個小型表單
  2. 利用 definitions:使用 JSON Schema 的 definitions 部分重用常見的模式
  3. 主題化:使用 RJSF 的主題支持,確保表單與應用程序的整體設計一致
  4. 性能優化:對於大型表單,考慮使用記憶化技術減少不必要的重新渲染

結論

React JSONSchema Form 代表了一種强大而靈活的表單構建方法,通過聲明式的 JSON Schema 定義數據結構,同時提供豐富的自定義選項。它特別適合動態表單生成和快速開發場景,與傳統的命令式表單庫形成了有益的互補。

雖然 React Hook Form 等庫在某些極端性能需求的情況下可能更合適,但 RJSF 的聲明式方法和自動化功能使其成為許多 Web 開發者的首選。通過掌握其自定義機制,開發者可以創建既符合業務邏輯又提供出色用戶體驗的表單界面。

關於 Calpa

Calpa 擅長使用 TypeScriptReact.jsVue.js 建立 Responsive Website。

他積極參與開源社區,曾在 2019 年的香港開源大會上擔任講者,提供工作經驗和見解。此外,他也在 GitHub 上公開分享個人博客程式碼,已獲得超過 300 顆星星和 60 個分支的支持。

他熱愛學習新技術,並樂意分享經驗。他相信,唯有不斷學習才能跟上快速演變的技術環境。

熱門文章

最新文章

Vibe Coding Idea Lab:AI 共創 × 靈感實作 × MVP 引爆場
精選來自超過 700 位學員、Discord 社群與線上共創活動的 idea。我們用 AI 快速落實創意,用 prompt 引爆行動,用共創測試價值。現有 ${ideas.length} 個 idea,歡迎隨緣分享。
圖片管理中心
管理圖片資源
IP 查詢
快速查詢和定位 IP 地址的地理位置和相關信息
Python 運行器
無需後端、無需登入,只需打開瀏覽器即可運行 Python 代碼(由 Pyodide 提供支持)
封面圖生成器
自動創建適合各種平台的文章封面圖
原作(青山剛昌)產生器
一鍵創建原作(青山剛昌)的封面圖
日本色彩
探索和使用傳統日本色彩
部落格內容洞察儀表板
以視覺化儀表板方式追蹤文章成效、分享熱度與分類分布,協助創作者掌握內容表現。
蒙特卡羅估算 π
使用蒙特卡羅方法演示 π 值的估算過程
LLM
使用 LLM 模型進行聊天
活動圖生成器
一鍵創建活動的封面圖
Wagmi Card
一鍵創建 Wagmi 的封面圖
Facebook Quote
Facebook Quote
Music Macro Language (MML) Studio
用程式語法編寫旋律,用音符構築想像
Blurhash
一鍵創建 Blurhash
文字分類器
使用 MediaPipe TextClassifier 分類文字
前端工程師免費工具資源
前端工程師免費工具資源
後端工程師免費工具資源
後端工程師免費工具資源
全端工程師免費工具資源
全端工程師免費工具資源
Web3 工程師免費工具資源
Web3 工程師免費工具資源
紫微斗數排盤系統|結合 AI 的命盤性格與事業財務分析生成器
紫微斗數排盤工具,輸入生日與時辰,自動生成完整命盤分析提示(Prompt)。結合最專業紫微理論與 AI 助力,助你深入解析性格、事業、財務與人際課題。免費使用,適合命理師及紫微愛好者。
PixAI Prompt 組合器|快速打造可用於 AI 繪圖的語言拼圖
使用 PixAI 卻不會寫 prompt?這個工具幫你一鍵組裝角色、表情、風格語彙,輸出高品質繪圖提示語句(Prompt),可直接貼入 PixAI 使用。適合插畫師、創作者、AI 新手與 VTuber 角色開發者。
你擁有的 .eth 是誰?一鍵查出 ENS 背後地址
只要輸入一個 ENS 名稱,我們就能幫你查出它指向哪個以太坊地址,還能看到頭像。如果你常常看到 .eth 名稱卻不知道誰在背後,這個小工具幫得上忙。
水果切割圖生成器