我用AI把重复的React组件自动生成,结果省下了两天工期
上个月接了个后台管理系统的活,需求里光表格就有12个。每个表格列的字段不一样、操作按钮不同、筛选条件各异,但底层逻辑——数据请求、分页、loading态、空态——一模一样。
第一个我手写了3小时。写到第五个的时候,我已经进入了一种麻木的复制粘贴改字段的机器人状态。写到第八个,我看了眼项目排期,还有两天就要交付。
这时候我开始想:这些组件的差异在哪里,共性又在哪里? 如果能把90%的共性代码交给AI,我只改那10%的不同,是不是有救?
答案是:能。而且我不仅赶上了ddl,还多出来半天重构了旧代码。
整体思路:先抽象,再生成
核心就三步:
- 把重复逻辑抽象成模板 — 参数化组件,提取变化点(列定义、API端点、筛选字段)
- 写一个AI Prompt模板 — 告诉AI这个组件的结构和变化维度,每次只需输入差异
- 批量生成 — 一次性扔给AI,一次拿到12个文件
关键点在于:不要直接让AI凭空写,你得先教会它你的模式。
具体操作步骤
第一步:先手写一个「母版组件」
我挑了一个最典型的表格,把变化的部分都抽成 props 和配置对象。简化后大概这样:
interface TableConfig<T> {
columns: ColumnType<T>[]
apiEndpoint: string
searchFields?: string[]
rowActions?: (row: T) => ReactNode[]
}
function GenericTable<T>({ config }: { config: TableConfig<T> }) {
const [data, setData] = useState<T[]>([])
const [loading, setLoading] = useState(false)
const [page, setPage] = useState(1)
useEffect(() => {
setLoading(true)
fetch(`${config.apiEndpoint}?page=${page}`)
.then(res => res.json())
.then(res => setData(res.list))
.finally(() => setLoading(false))
}, [page, config.apiEndpoint])
if (loading) return <Spin />
if (data.length === 0) return <Empty />
return (
<Table columns={config.columns} dataSource={data} />
)
}
第二步:写Prompt模板
关键是把你的「模式」喂给 AI。我用的 prompt 长这样:
你是一个React高级开发。下面是一个通用表格组件的使用模式:
<GenericTable
config={{
apiEndpoint: string,
columns: ColumnType[],
searchFields: string[],
rowActions: (row) => []
}}
/>
现在请根据以下需求生成完整代码文件:
- 模块名:用户管理
- API端点:/api/users
- 列:用户名、邮箱、手机号、注册时间、状态(启用/禁用)
- 搜索字段:用户名、邮箱
- 行操作:编辑、禁用/启用切换
- 额外需求:状态列用Tag组件展示颜色区分
输出一个可直接运行的tsx文件。
第三步:批量丢给Claude
我把12个模块的差异写成一张表,一次发给AI:
帮我用上述模板生成以下12个表格模块,每个输出一个tsx文件:
1. 用户管理 | /api/users | 用户名/邮箱/手机号/注册时间/状态 | 搜索:用户名,邮箱
2. 订单管理 | /api/orders | 订单号/用户/金额/状态/创建时间 | 搜索:订单号
3. 商品管理 | /api/products | 商品名/分类/价格/库存/状态 | 搜索:商品名,分类
...
大概3分钟,AI把12个文件全部输出。我逐个检查、微调,总共花了不到2小时。
代码对比:手写 vs AI生成
手写一个表格组件(约120行):
function OrderTable() {
const [loading, setLoading] = useState(true)
const [data, setData] = useState([])
const [page, setPage] = useState(1)
const [total, setTotal] = useState(0)
useEffect(() => {
fetch(`/api/orders?page=${page}&pageSize=20`)
.then(r => r.json())
.then(r => { setData(r.list); setTotal(r.total) })
.finally(() => setLoading(false))
}, [page])
const columns = [
{ title: '订单号', dataIndex: 'orderNo' },
{ title: '用户', dataIndex: 'username' },
{ title: '金额', dataIndex: 'amount', render: v => `¥${v}` },
{ title: '状态', dataIndex: 'status' },
]
return (
<Table
loading={loading}
dataSource={data}
columns={columns}
pagination={{ current: page, total, onChange: setPage }}
/>
)
}
AI基于模板生成(约40行差异代码):
function OrderTable() {
return (
<GenericTable
config={{
apiEndpoint: '/api/orders',
columns: [
{ title: '订单号', dataIndex: 'orderNo' },
{ title: '用户', dataIndex: 'username' },
{ title: '金额', dataIndex: 'amount', render: v => `¥${v}` },
{ title: '状态', dataIndex: 'status' },
],
searchFields: ['orderNo'],
}}
/>
)
}
12个表格,从近1500行手写代码,降到约500行(其中大部分是列定义这种真正有业务价值的代码)。
踩坑点
1. AI不会自动替你「最佳实践」
第一次生成时,AI把 GenericTable 写成了 any 大法,类型安全全丢了。解决方案:在母版组件里就把 TypeScript 泛型写好,在 prompt 里明确要求「保留完整类型」。
2. 模板不能太灵活,也不能太死
一开始我把模板搞得太抽象,期望 AI 能处理各种边界情况。结果 AI 生成出来的代码总有一些奇怪的兼容处理,导致运行时暴错。后来我只提取95%场景下的共同模式,剩下5%的差异化直接写在各组件里覆写。
3. AI会「忘记」你的命名规范
给12个文件命名,AI最后除了两个 index.tsx,还有叫 UserListPage.tsx、user-table.tsx、userManagement.tsx 的。一定要在 prompt 里强调文件命名规范。
4. 别让AI一口气生成太多
试过一次让它生成20个,结果到第15个就开始掉 token 质量下降。建议每批5-8个,分批生成,质量可控。
总结
这次之后我自己的工作流变成了这样:
- 人工 — 手写1个母版组件(1-2小时)
- AI — 批量生成N个变体(几分钟)
- 人工 — 逐个review + 跑测试(半小时-1小时)
整体效率至少提升了3-4倍。而且心态完全变了——以前看到重复组件就头大,现在反而有点期待:又能练一次 Prompt 技巧了 🎯
给一个可执行的建议:
下次接到重复组件多的需求,别急着敲键盘。先花15分钟想清楚「哪些是共性,哪些是差异」,写一个配置驱动的基础组件,然后给AI喂一个带示例的 prompt。你只需要把那15%真正有业务逻辑差异的部分写好,剩下的交给 AI 去填空。
这玩意儿不神秘,就是个「把费时的重复劳动外包出去」的思路。AI是你的实习生,你是那个把关的 senior —— 听起来是不是舒服多了?