React Refine中如何在表单字段优雅展示并编辑JSON数据
问题描述
从后端REST API获取到如下JSON数据:
{ "id": "bb8dc1fa84d842bd82e3494f2d9b8e49_LATEST", "status": "publish", "version": "LATEST", "permission_document": { "Version": "2023-05-22", "Statement": ["*"], "Signature": "9434903948034389439843834900920-320-3-2024904209429049033490430--340" } }
需要在基于Refine框架的React表单中展示并允许编辑permission_document字段,编辑后提交回后端。当前使用的表单代码如下:
import React from "react"; import { IResourceComponentsProps } from "@refinedev/core"; import { Edit, useForm, useFileUploadState } from "@refinedev/antd"; import { Form } from "antd"; import MDEditor from "@uiw/react-md-editor"; import { IPermissionDocument } from "interfaces"; export const PermissionDocumentEdit: React.FC<IResourceComponentsProps> = () => { const { formProps, saveButtonProps } = useForm<IPermissionDocument>(); return ( <Edit saveButtonProps={{ ...saveButtonProps }}> <Form {...formProps} layout="vertical"> <Form.Item label="Permission Document" name="permission_document" rules={[ { required: true, }, ]} > <MDEditor id="permission_document" preview='edit' data-color-mode="light" /> </Form.Item> </Form> </Edit> ); };
当前问题是无法以格式化、美观的JSON形式展示该字段,编辑体验差。
解决方案
方案一:使用专门的JSON编辑组件(推荐)
采用react-json-editor-ajrm组件,支持格式化显示、语法高亮、节点级编辑,适配表单场景。
步骤1:安装依赖
npm install react-json-editor-ajrm --save # 或yarn yarn add react-json-editor-ajrm
步骤2:修改表单代码
替换原MDEditor为JSON编辑器,处理Form值的双向绑定:
import React from "react"; import { IResourceComponentsProps } from "@refinedev/core"; import { Edit, useForm } from "@refinedev/antd"; import { Form } from "antd"; import JsonEditor from "react-json-editor-ajrm"; import locale from "react-json-editor-ajrm/locale/en"; import { IPermissionDocument } from "interfaces"; export const PermissionDocumentEdit: React.FC<IResourceComponentsProps> = () => { const { formProps, saveButtonProps } = useForm<IPermissionDocument>(); return ( <Edit saveButtonProps={{ ...saveButtonProps }}> <Form {...formProps} layout="vertical"> <Form.Item label="Permission Document" name="permission_document" rules={[ { required: true, message: "请填写权限文档" }, ]} getValueProps={(value) => ({ value: value || {} })} > <JsonEditor locale={locale} height="400px" placeholder={{}} theme="light" onChange={(e) => { formProps.form.setFieldsValue({ permission_document: e.jsObject }); }} /> </Form.Item> </Form> </Edit> ); };
方案二:使用Antd TextArea配合JSON格式化(轻量方案)
无需额外依赖,用TextArea手动处理JSON的格式化与解析:
import React from "react"; import { IResourceComponentsProps } from "@refinedev/core"; import { Edit, useForm } from "@refinedev/antd"; import { Form, TextArea } from "antd"; import { IPermissionDocument } from "interfaces"; export const PermissionDocumentEdit: React.FC<IResourceComponentsProps> = () => { const { formProps, saveButtonProps } = useForm<IPermissionDocument>(); return ( <Edit saveButtonProps={{ ...saveButtonProps }}> <Form {...formProps} layout="vertical"> <Form.Item label="Permission Document" name="permission_document" rules={[ { required: true, message: "请填写权限文档" }, { validator(_, value) { try { if (typeof value === "string") JSON.parse(value); return Promise.resolve(); } catch (err) { return Promise.reject(new Error("请输入合法的JSON格式")); } } } ]} getValueProps={(value) => ({ value: typeof value === "object" ? JSON.stringify(value, null, 2) : value })} normalize={(value) => { try { return value ? JSON.parse(value) : {}; } catch (err) { return value; } }} > <TextArea rows={10} placeholder="请输入JSON格式的权限文档" /> </Form.Item> </Form> </Edit> ); };
方案说明
- 方案一适合复杂编辑场景,支持节点增删、语法高亮,用户体验更佳;
- 方案二更轻量,无需额外依赖,适合简单文本编辑需求;
- 两种方案均能与Refine的
useForm无缝配合,提交时自动转换为后端所需的JSON格式。
内容的提问来源于stack exchange,提问作者Roel den blanken
相关产品推荐
相关产品推荐

