# react-jsonschema-form:使用json schema创建react表单

**React JSON Schema Form (rjsf)** 是一个由Mozilla开发的React库,他可以将JSON Schema转换为HTML表单。它提供了一种声明式的方式来创建和验证表单,使得开发者可以更专注于数据本身,而不是表单的具体实现。

rjsf github:https://github.com/rjsf-team/react-jsonschema-form

rjsf demo: https://rjsf-team.github.io/react-jsonschema-form/

## 示例

以下是一个简单的例子,展示了如何使用rjsf创建一个表单

Language
Copy code
``` import Head from 'next/head' import styled from 'styled-components'; import React from "react"; import Form from '@rjsf/bootstrap-4'; import validator from "@rjsf/validator-ajv8"; const schema = { "type": "object", "required": ["priority", "summary"], "properties": { "state": { "type": "string", "title": "状态", "oneOf": [ {"const": 'Todo', "title": "未开始"}, {"const": 'Start', "title": "开始"}, {"const": 'Done', "title": "已完成"}, ], "default": 'Start', }, "summary": { "type": "string", "title": "概述" }, "priority": { "type": "string", "title": "优先级", "oneOf": [ {"const": 'Low', "title": "低"}, {"const": 'Medium', "title": "中"}, {"const": 'High', "title": "高"}, {"const": 'Urgent', "title": "紧急"}, ], "default": 'High', }, "startAt": { "type": "string", "title": "开始时间", "format": "date-time" }, "endAt": { "type": "string", "title": "截止时间", "format": "date-time" }, "describe": { "type": "string", "title": "描述" }, } } export default function Home() { return ( <> <Head> <link href={`/bootstrap-dark.min.css`} rel="stylesheet" /> </Head> <ContainerSC> <Form schema={schema} validator={validator} onChange={console.log} onSubmit={console.log} onError={console.log} /> </ContainerSC> </> ) } const ContainerSC = styled('div')` min-height: 100vh; position: fixed; left: 0; top: 0; right: 0; bottom: 0; box-sizing: border-box; display: flex; background: rgb(49, 49, 49); color: #BFBFBF; padding-left: 400px; padding-top: 100px; `;   ```

**渲染出的效果:**

![01H8DZCN3VVD98J5A5MZ00X08K](https://just-blog.oss-cn-hangzhou.aliyuncs.com/images/01H8DZCN3VVD98J5A5MZ00X08K.png)![01H8DZCN3VVD98J5A5MZ00X08K](https://just-blog.oss-cn-hangzhou.aliyuncs.com/images/01H8DZCN3VVD98J5A5MZ00X08K.png)

## rjsf的一些主要特性

  1. 1.

    **基于JSON Schema**: 你可以使用JSON Schema来描述你的表单的结构和验证规则。JSON Schema是一个用于描述JSON数据格式的标准,它提供了一种简单和通用的方式来定义数据的类型、格式、验证规则

  2. 2.

    **自动生成表单**:rjsf可以根据你的JSON Schema自动生成对应的HTML表单。你无需手动创建每一个表单元素,只需要提供一个描述表单的JSON Schema, rjsf就回为你创建一个完整的表单。

  3. 3.

    **内置验证**:rjsf支持JSON Schema的所有验证关键字,包括类型验证、格式验证、枚举验证等。当用户提交表单时,rjsf会自动验证表单数据是否符合你的JSON Schema。

  4. 4.

    **可定制和可扩展**:rjsf提供了多种定制和扩展的方式。你可以定制表单的外观和行为,例如自定义主题、自定义字段、自定义小部件等。你也可以扩展rjsf的功能,例如添加自定义的验证规则、添加自定义的表单逻辑等。

  5. 5.

    **支持复杂的表单结构**:rjsf支持JSON Schema的所有数据结构,包括数组、对象、嵌套结构等。你可以创建任意复杂的表单,而无需担心表单的实现细节。

## `uiSchema`和自定义组件

Language
Copy code
```js const StartAtWidget = function (props) { const { value, onChange, registry, } = props; const DefaultDateTimeWidget = registry.widgets.DateTimeWidget; const setNow = (e) => { e.preventDefault(); console.log('Button clicked!'); const date = new Date(); date.setSeconds(0,0); const utcString = date.toUTCString(); onChange(utcString); }; const setTomorrow = (e) => { e.preventDefault(); const date = dayjs() .add(1, 'day') .set('hour', 6) .set('minute', 0) .set('second', 0) .toDate(); const utcString = date.toUTCString(); onChange(utcString); } const addOneDay = (e) => { e.preventDefault(); const date = dayjs(value) .add(1, 'day') .set('second', 0) .toDate(); const utcString = date.toUTCString(); onChange(utcString); } return ( <div> <DefaultDateTimeWidget {...props} /> <TimeButtonSC className="btn-group" role="group" aria-label="Basic example"> <button type="button" className="btn btn-outline-secondary" onClick={setNow}>现在</button> <button type="button" className="btn btn-outline-secondary" onClick={setTomorrow}>明早</button> <button type="button" className="btn btn-outline-secondary" onClick={addOneDay}>+一天</button> </TimeButtonSC> </div> ); }; const uiSchema = { "describe": { "ui:widget": "textarea", }, startAt: { "ui:widget": "StartAtWidget", } } const customerWidgets = { StartAtWidget, }; export default function Home() { return ( <> <Head> <link href={`/bootstrap-dark.min.css`} rel="stylesheet" /> </Head> <ContainerSC> <Form uiSchema={uiSchema} schema={schema} widgets={customerWidgets} validator={validator} onChange={console.log} onSubmit={console.log} onError={console.log} /> </ContainerSC> </> ) } const TimeButtonSC = styled('div')` margin-top: 5px; `;   ```

**渲染效果:**

![01H8E0CZ6MRVMRPKQQYSWP3T71](https://just-blog.oss-cn-hangzhou.aliyuncs.com/images/01H8E0CZ6MRVMRPKQQYSWP3T71.png)![01H8E0CZ6MRVMRPKQQYSWP3T71](https://just-blog.oss-cn-hangzhou.aliyuncs.com/images/01H8E0CZ6MRVMRPKQQYSWP3T71.png)

## 应用场景

  1. 1.

    **动态表单生成**:在需要根据后端返回的数据动态生成表单的场景中,rjsf可以大大简化开发流程。只需要后端提供JSON Schema, 前端就可以根据这个Schema生成对应的表单,而无需手动编写大量的表单代码

  2. 2.

    **复杂表单结构**:对于包含嵌套字段、数组、条件字段等复杂结构的表单,使用rjsf可以方便地处理这些复杂情况。

  3. 3.

    **表单验证**:rjsf内置了基于JSON Schema的表单验证功能,可以方便地对表单输入进行各种复杂的验证,例如类型验证、格式验证、枚举验证等

  4. 4.

    **表单定制和扩展**:如果你需要定制表单的外观和行为,或者添加自定义的表单逻辑,rjsf提供了多种定制和扩展的方式。

  5. 5.

    **跨平台开发**:由于JSON Schema是一个通用的数据描述语言,所以你可以使用同一个Schema在不同的平台生成相同的表单