react-admin4.13中ReferenceArrayInput parse/format致请求报错
react-admin 4.13 嵌套关联输入组件数据转换报错解决方案
问题描述
使用react-admin 4.13开发时,为ReferenceArrayInput嵌套的AutocompleteArrayInput配置parse、format方法做数据转换,会出现parse逻辑篡改fetch请求属性值的问题,最终导致接口报错。
问题复现代码:
<ReferenceArrayInput source="locations" reference="locations" filter={{ type: LOCATION_TYPE.SITE }} > <AutocompleteArrayInput optionText="name" format={(list: Array<{ id: string }> = []) => list.map((i) => i.id)} parse={(list: Array<string> = []) => list.map((id) => ({ id }))} /> </ReferenceArrayInput>
参考截图:

问题原因
配置的转换层级完全错误:
ReferenceArrayInput内部约定绑定的source字段值必须是纯ID数组,组件会自行根据ID数组拉取对应关联记录、把选中的ID数组同步给表单最终提交值。- 在子组件
AutocompleteArrayInput上定义的parse会把选中的ID数组转成{id: xxx}结构的对象数组,这个值会直接覆盖表单里locations字段的最终提交值,接口预期接收ID数组,实际拿到对象数组,必然触发报错。 - 自定义的
format逻辑还会干扰ReferenceArrayInput内部的选项匹配逻辑,导致组件选中状态异常。
正确配置方式
场景1:接口返回/接收的locations字段本身是ID数组
这种场景完全不需要自定义parse和format,ReferenceArrayInput + AutocompleteArrayInput的组合已经内置了值适配逻辑,直接删掉自定义转换即可:
<ReferenceArrayInput source="locations" reference="locations" filter={{ type: LOCATION_TYPE.SITE }} > <AutocompleteArrayInput optionText="name" /> </ReferenceArrayInput>
场景2:接口返回的locations字段是带id的对象数组,提交需要转ID数组
这种场景不要在输入组件上做转换,把转换逻辑放在数据进出表单的两个边界节点处理:
- 数据流入表单前(接口返回后):在
dataProvider的getOne、getMany等方法的响应拦截里,把locations对象数组转成纯ID数组,再传给表单,保证ReferenceArrayInput拿到的初始值是符合要求的ID数组。 - 数据流出提交时(表单提交后):在Edit/Create视图的
transform属性里,把提交数据里的locations字段做对应格式转换再发给接口,示例:
const SiteEdit = () => ( <Edit transform={(data) => ({ ...data, // 提交时需要对象结构就在这里转换,不要在输入组件内部处理 locations: data.locations.map(id => ({ id })) })} > <SimpleForm> <ReferenceArrayInput source="locations" reference="locations" filter={{ type: LOCATION_TYPE.SITE }} > <AutocompleteArrayInput optionText="name" /> </ReferenceArrayInput> </SimpleForm> </Edit> )
核心规则:所有和接口层的数据格式转换,都不要放在
ReferenceArrayInput的子输入组件上处理,避免破坏组件内部的状态同步逻辑,导致提交值异常。
内容的提问来源于stack exchange,提问作者Peam
相关产品推荐
相关产品推荐

