如何使用React-Admin输入并创建两个及以上独立数据库字段
实现方法
AutocompleteInput 原生仅支持通过optionValue指定单个字段绑定到source对应的表单属性,要实现选中后同时写入多个独立数据库字段,不需要魔改组件,用下面两种方案都可以实现,最终提交的都是平级的独立字段,不会嵌套成对象。
方案1:选中时实时赋值(推荐)
借助react-admin表单提供的useFormContext钩子拿到表单赋值方法,监听组件的onChange事件,选中选项后手动给多个目标字段赋值即可。
import { AutocompleteInput, useFormContext } from 'react-admin'; import { useCallback } from 'react'; const AuthorSelect = () => { const { setValue } = useFormContext(); const choices = [ { id: 123, first_name: 'Leo', last_name: 'Tolstoi' }, { id: 456, first_name: 'Jane', last_name: 'Austen' }, ]; const optionRenderer = choice => `${choice.first_name} ${choice.last_name}`; const handleAuthorChange = useCallback((_, selectedItem) => { // 选中项为空(清空选择)时重置所有关联字段 if (!selectedItem) { setValue('author_id', null); setValue('author_first_name', null); setValue('author_last_name', null); return; } // 分别给三个独立字段赋值 setValue('author_id', selectedItem.id); setValue('author_first_name', selectedItem.first_name); setValue('author_last_name', selectedItem.last_name); }, [setValue]); return ( <AutocompleteInput source="author_id" choices={choices} optionText={optionRenderer} optionValue="id" onChange={handleAuthorChange} /> ); };
这个方案的好处是字段值在表单里实时同步,做联动校验、字段联动显示的时候不会有延迟。
方案2:提交前统一拆分字段
如果不想在交互阶段处理赋值逻辑,也可以在表单提交的钩子中,根据选中的主键值反查完整选项,拆分出需要的字段再提交给后端。
import { Create, SimpleForm, AutocompleteInput } from 'react-admin'; const ArticleCreate = () => { const authorChoices = [ { id: 123, first_name: 'Leo', last_name: 'Tolstoi' }, { id: 456, first_name: 'Jane', last_name: 'Austen' }, ]; const optionRenderer = choice => `${choice.first_name} ${choice.last_name}`; // 提交数据前做格式转换 const transformSubmitData = (formData) => { const matchedAuthor = authorChoices.find(item => item.id === formData.author_id); return { ...formData, author_first_name: matchedAuthor?.first_name, author_last_name: matchedAuthor?.last_name }; }; return ( <Create transform={transformSubmitData}> <SimpleForm> {/* 其余表单字段 */} <AutocompleteInput source="author_id" choices={authorChoices} optionText={optionRenderer} optionValue="id" /> </SimpleForm> </Create> ); };
避坑提示:不要直接把
optionValue设置为整个选项对象,这种方式会让表单存储引用类型值,后续做字段对比、序列化提交的时候很容易出现异常,上面两种方案都用id这个基础类型做绑定,稳定性更好。
内容的提问来源于stack exchange,提问作者Eshaan Gupta
相关产品推荐
相关产品推荐

