在當今的 Web 開發中,表單是與用戶交互的最重要界面之一。對於 React 開發者來說,有多種表單解決方案可供選擇,其中 React JSONSchema Form (RJSF) 以其獨特的方式脫穎而出。本文將深入探討這個強大的表單庫,了解如何利用它構建複雜表單,以及如何通過自定義組件提升用戶體驗。
React JSONSchema Form 是一個能夠基於 JSON Schema 自動生成 HTML 表單的 React 組件。它的核心理念是:只需提供一個 JSON Schema 描述數據結構,就能自動生成對應的表單界面。這種方法特別適合處理動態生成的表單,或者基於後端 API 響應構建表單的場景。

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")}
/>
);
構建複雜表單的關鍵技術

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
屬性標記必填字段,或使用各種驗證關鍵字(如 minimum
、maximum
、pattern
等)定義更複雜的驗證規則。
與其他表單構建庫的比較
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:更適合完全自定義的表單,對每個字段的行為都需要精確控制
自定義組件:提升表單界面

RJSF 真正的強大之處在於其可擴展性,允許開發者完全自定義表單的外觀和行為。
自定義 Widgets
Widgets 表示用戶輸入數據的 HTML 標籤,如 input
、select
等。通過自定義 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 特別適合以下場景:
- 動態表單:根據用戶選擇或 API 響應動態調整表單結構
- 管理界面:通過 JSON Schema 快速生成 CRUD 操作界面
- 複雜的多步驟表單:結合自定義模板創建分步驟表單體驗
- 基於配置的表單系統:允許非技術人員通過配置定義表單
使用技巧與最佳實踐
- 分解複雜表單:對於非常複雜的表單,考慮將其分解為多個小型表單
- 利用 definitions:使用 JSON Schema 的
definitions
部分重用常見的模式 - 主題化:使用 RJSF 的主題支持,確保表單與應用程序的整體設計一致
- 性能優化:對於大型表單,考慮使用記憶化技術減少不必要的重新渲染
結論
React JSONSchema Form 代表了一種强大而靈活的表單構建方法,通過聲明式的 JSON Schema 定義數據結構,同時提供豐富的自定義選項。它特別適合動態表單生成和快速開發場景,與傳統的命令式表單庫形成了有益的互補。
雖然 React Hook Form 等庫在某些極端性能需求的情況下可能更合適,但 RJSF 的聲明式方法和自動化功能使其成為許多 Web 開發者的首選。通過掌握其自定義機制,開發者可以創建既符合業務邏輯又提供出色用戶體驗的表單界面。