如何在SimpleForm中排除指定字段不随表单提交?
解决React-Admin中提交时携带未渲染字段的问题
这问题我之前也碰到过!当你用基于redux-form的<SimpleForm>编辑User实体时,redux-form会默认把GET_ONE返回的所有initialValues都包含在提交数据里——哪怕你没在表单里添加对应字段的输入组件,所以type字段会被一起提交。想要保留type给<Show>等组件用,又不想硬编码修改RestClient,试试这几个优雅的方案:
方案1:用<SimpleForm>的transform属性过滤提交数据
这是最直接且符合react-admin设计的方式,在表单提交前对数据做一次清洗,去掉不需要的字段:
import { Edit, SimpleForm, TextInput, NumberInput } from 'react-admin'; const UserEdit = (props) => ( <Edit {...props}> <SimpleForm // 提交前过滤掉type字段 transform={(formData) => { const { type, ...filteredData } = formData; return filteredData; }} > <TextInput source="name" /> <NumberInput source="age" /> </SimpleForm> </Edit> ); export default UserEdit;
这个方法的优势很明显:
- 完全不影响
<Show>组件对type字段的使用,因为<Show>直接读取API返回的原始数据,和表单提交的处理逻辑无关 - 不需要修改RestClient或dataProvider,完美契合你不想硬编码的需求
- 逻辑清晰,只在表单提交环节针对性处理数据
方案2:手动控制表单的initialValues(进阶)
如果你需要更精细的控制,也可以在<Edit>组件里手动获取数据,只把表单需要的字段传给它当initialValues:
import { useGetOne, Edit, SimpleForm, TextInput, NumberInput } from 'react-admin'; const UserEdit = ({ id, ...props }) => { const { data, isLoading } = useGetOne('users', { id }); if (isLoading) return <div>Loading...</div>; // 只传递表单需要的字段作为initialValues const initialValues = { name: data.name, age: data.age, // 这里不传递type,表单就不会带上它提交 }; return ( <Edit {...props} initialValues={initialValues}> <SimpleForm> <TextInput source="name" /> <NumberInput source="age" /> </SimpleForm> </Edit> ); }; export default UserEdit;
这个方案适合需要对initialValues做更多自定义处理的场景,但相比方案1会多一些代码量。
为什么会出现这个问题?
本质是redux-form的默认行为:它会把initialValues里的所有字段都纳入表单的提交数据,不管你有没有渲染对应的输入组件。而react-admin的<Edit>组件默认会把GET_ONE返回的完整实体数据作为表单的initialValues,所以type字段会被自动包含进来。
内容的提问来源于stack exchange,提问作者llioor
相关产品推荐
相关产品推荐

