React-admin中如何访问JSON API响应嵌套值并编辑contacts字段
react-admin嵌套数组字段编辑解决方案
直接给TextInput绑定source="contacts"只会把整个数组序列化为纯文本展示,无法编辑内部嵌套结构,针对你的场景处理方式如下:
一、固定字段的contacts嵌套值查看/编辑
使用react-admin内置的ArrayInput+SimpleFormIterator组件处理数组类型字段,数组内每个对象的属性直接作为子输入组件的source即可,修正后的OrgEdit代码如下:
// 引入依赖组件 import { Edit, SimpleForm, TextInput, ArrayInput, SimpleFormIterator, BooleanInput } from 'react-admin'; export const OrgEdit = () => ( <Edit title={<OrgTitle />}> <SimpleForm sanitizeEmptyValues> <TextInput disabled source="orgid" /> <TextInput disabled source="arn" /> <TextInput source="orgnamefriendly" label="组织名称" /> <TextInput disabled source="parentid" /> {/* 嵌套contacts数组处理 */} <ArrayInput source="contacts" label="联系人列表"> <SimpleFormIterator> <TextInput source="name" label="联系人姓名" /> <TextInput source="email" label="联系邮箱" /> <BooleanInput source="alertoptin" label="接收告警通知" parse={val => val ? "True" : "False"} format={val => val === "True"} /> <BooleanInput source="billingoptin" label="接收账单通知" parse={val => val ? "True" : "False"} format={val => val === "True"} /> <BooleanInput source="orgtechcontact" label="技术联系人" parse={val => val ? "True" : "False"} format={val => val === "True"} /> <BooleanInput source="orgbillingcontact" label="账单联系人" parse={val => val ? "True" : "False"} format={val => val === "True"} /> </SimpleFormIterator> </ArrayInput> </SimpleForm> </Edit> );
注:原代码中Edit的title属性外层多了单引号,会导致JSX被当做普通字符串渲染,已在上述代码中修正。接口返回的布尔类字段是字符串格式的
"True"/"False",通过parse/format做双向转换即可和BooleanInput组件适配。
二、动态键值对适配
contacts字段的动态键值对完全支持适配,根据动态键的可预知程度选择对应方案:
- 动态键范围已知:直接在
SimpleFormIterator内声明所有可能出现的字段即可,开启sanitizeEmptyValues后,当前数据里不存在的字段不会被提交到后端,不会产生冗余字段。 - 动态键完全不可预知:自定义输入组件遍历当前数组项的所有键,动态渲染对应输入控件即可,参考实现如下:
import { useInput, TextInput, BooleanInput } from 'react-admin'; const DynamicContactItem = () => { // 绑定当前数组项的根路径 const { field } = useInput({ source: '' }); const currentContact = field.value || {}; // 固定字段列表,遍历时过滤避免重复渲染 const fixedKeys = ['name','email','alertoptin','billingoptin','orgtechcontact','orgbillingcontact']; return ( <> {/* 渲染固定字段 */} <TextInput source="name" label="联系人姓名" /> <TextInput source="email" label="联系邮箱" /> <BooleanInput source="alertoptin" label="接收告警通知" parse={val => val ? "True" : "False"} format={val => val === "True"} /> <BooleanInput source="billingoptin" label="接收账单通知" parse={val => val ? "True" : "False"} format={val => val === "True"} /> <BooleanInput source="orgtechcontact" label="技术联系人" parse={val => val ? "True" : "False"} format={val => val === "True"} /> <BooleanInput source="orgbillingcontact" label="账单联系人" parse={val => val ? "True" : "False"} format={val => val === "True"} /> {/* 动态渲染剩余自定义字段 */} {Object.keys(currentContact) .filter(key => !fixedKeys.includes(key)) .map(dynKey => <TextInput key={dynKey} source={dynKey} label={dynKey} />) } </> ) } // 替换原有ArrayInput内的子内容即可 <ArrayInput source="contacts" label="联系人列表"> <SimpleFormIterator> <DynamicContactItem /> </SimpleFormIterator> </ArrayInput>
如果需要支持用户手动新增自定义键值对,可以在自定义组件里补充键名输入、值输入、新增/删除的交互逻辑,最终将新增的键值对挂载到当前数组项对象上,react-admin表单会自动收集所有字段值按结构提交。如果当前使用的dataProvider默认会把嵌套数组序列化成字符串,只需要在dataProvider的update、create方法里加一层转换,保证contacts按原始数组结构传给接口即可。
内容的提问来源于stack exchange,提问作者MrDane215
相关产品推荐
相关产品推荐

