React-Admin中实现Clone按钮(TypeScript):克隆记录并新建条目
实现React-Admin中的克隆记录功能
嘿,这个需求很常见!你的Clone按钮本质上是增强版的Create功能——它不是修改现有记录(那是EditButton的活),而是带着被克隆记录的预填充数据打开创建表单,最终提交生成一条全新的条目。下面是具体的实现步骤:
1. 自定义CloneButton组件
React-Admin自带的<CloneButton>其实已经有基础功能,但我们可以封装一个更贴合需求的版本,确保它正确跳转至Create页面并携带原记录的数据:
import { useRecordContext, useNavigate } from 'react-admin'; import { Button } from '@mui/material'; import ContentCopyIcon from '@mui/icons-material/ContentCopy'; export const CloneButton = ({ basePath }: { basePath: string }) => { const record = useRecordContext(); const navigate = useNavigate(); const handleClone = () => { // 移除主键(比如id)和不需要克隆的字段,避免提交时干扰新记录创建 const { id, status, ...cloneData } = record; // 自动给名称加克隆后缀,方便区分原记录 cloneData.name = `${cloneData.name} [Clone]`; // 跳转到Create页面,把克隆数据存在location.state中 navigate(`${basePath}/create`, { state: { record: cloneData } }); }; return ( <Button onClick={handleClone} startIcon={<ContentCopyIcon />} color="primary" > Clone </Button> ); };
然后在你的Datagrid里替换原有按钮:
<Datagrid rowStyle={modelRowStyle}> <TextField source="format" /> <TextField source="status" /> <EditButton basePath="/models" /> <DeleteButton basePath="/models" /> <CloneButton basePath="/models" /> </Datagrid>
2. 修改ModelCreate组件,接收克隆数据
现在需要让Create组件读取跳转时携带的初始数据,并用它填充表单。我们可以通过useLocation钩子获取state里的记录,传递给SimpleForm的initialValues:
import { Create, SimpleForm, TextInput, SelectInput, useLocation } from 'react-admin'; import { ModelCreateToolbar } from './ModelCreateToolbar'; export const ModelCreate = (props: any) => { const location = useLocation(); // 从路由状态中获取克隆数据,没有则用空对象 const initialValues = location.state?.record || {}; // 动态设置标题,区分普通创建和克隆场景 const pageTitle = initialValues.name ? `Clone Model: ${initialValues.name}` : "Create a Model"; return ( <Create title={pageTitle} {...props}> <SimpleForm toolbar={<ModelCreateToolbar />} initialValues={initialValues} > <TextInput source="name" label="Name" autoWidth={true} /> <TextInput source="version" label="Version" /> <SelectInput source="format" label="Format" choices={Format} optionText="name" optionValue="format" /> <SelectInput source="group" label="Group" choices={Group} optionText="name" optionValue="group" /> </SimpleForm> </Create> ); };
3. 确认提交逻辑
因为我们用的是<Create>组件,它默认会调用数据提供者的create方法,提交时会自动生成新记录,完全不会影响原有的被克隆条目——这正是我们需要的效果!
额外优化建议
- 如果有字段需要强制清空(比如创建时间、状态),可以在CloneButton的
handleClone里直接删除这些字段; - 版本号可以自动递增,比如
cloneData.version = (parseFloat(cloneData.version) + 0.1).toString(); - 可以给克隆后的表单添加提示,让用户知道这是克隆的记录。
这样整个克隆流程就完整了:点击Clone按钮后,带着原记录的预填充数据打开创建表单,用户修改后提交生成全新条目,完美匹配你的需求~
内容的提问来源于stack exchange,提问作者Anirudh Sharma
相关产品推荐
相关产品推荐

