🧠 React + TypeScript 打造“自带大脑”的客户信息录入系统(可保存、验证、回填)
普通表单只会收数据,智能表单能“教用户怎么填”。
今天我们用 React + TypeScript,构建一个“会自学、会判断、会校验”的客户录入平台,让你写表单像养宠物一样快乐!
✅ 为什么要写这篇?
汇丰内部的客户管理系统中,有大量的录入场景:开户资料、风控信息、地址认证、联系人等等。
如果只是做个 input + submit,那谁都会。
今天我们升级难度:构建一个会根据角色变化自动启用字段 + 支持实时保存 + 数据回填 + 智能提示的高级表单系统!
🧰 技术选型
| 技术 | 用途 |
|---|---|
| React + TS | 主体逻辑 |
| Zustand | 状态管理(轻量且好组合) |
| React Hook Form | 表单处理库(性能好) |
| Zod | 表单字段类型校验 |
| localStorage | 临时保存填写进度 |
📌 场景目标
实现一个客户录入表单,具备以下功能:
- ✅ 自动识别用户角色,启用不同字段
- ✅ 表单字段实时校验提示
- ✅ 离开页面再回来,自动回填填写进度
- ✅ 可扩展为 3 步表单、审批流程表单等
🧪 实战代码
1️⃣ 状态管理(Zustand)
// useFormStore.ts
import { create } from 'zustand'
type FormData = {
name: string
age: number
idNumber: string
contact: string
}
type State = {
data: Partial<FormData>
setData: (d: Partial<FormData>) => void
}
export const useFormStore = create<State>(set => ({
data: {},
setData: (d) => set(state => ({ data: { ...state.data, ...d } }))
}))
2️⃣ 表单实现(React Hook Form + Zod)
import { useForm } from 'react-hook-form'
import { zodResolver } from '@hookform/resolvers/zod'
import { z } from 'zod'
import { useFormStore } from './useFormStore'
const schema = z.object({
name: z.string().min(2),
age: z.number().min(18).max(120),
idNumber: z.string().length(18),
contact: z.string().email()
})
type FormInput = z.infer<typeof schema>
export function CustomerForm() {
const { data, setData } = useFormStore()
const { register, handleSubmit, watch, formState: { errors } } = useForm<FormInput>({
defaultValues: data as FormInput,
resolver: zodResolver(schema)
})
const onSubmit = (values: FormInput) => {
console.log('✅ 提交数据', values)
alert('客户信息提交成功!')
localStorage.removeItem('draft')
}
const onSave = () => {
const current = watch()
localStorage.setItem('draft', JSON.stringify(current))
alert('💾 保存草稿成功!')
}
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('name')} placeholder="姓名" />
{errors.name && <p>{errors.name.message}</p>}
<input type="number" {...register('age')} placeholder="年龄" />
{errors.age && <p>{errors.age.message}</p>}
<input {...register('idNumber')} placeholder="身份证号" />
{errors.idNumber && <p>{errors.idNumber.message}</p>}
<input {...register('contact')} placeholder="联系邮箱" />
{errors.contact && <p>{errors.contact.message}</p>}
<button type="submit">提交</button>
<button type="button" onClick={onSave}>保存草稿</button>
</form>
)
}
3️⃣ 页面加载时自动回填草稿
useEffect(() => {
const draft = localStorage.getItem('draft')
if (draft) {
setData(JSON.parse(draft))
alert('📂 已加载上次填写内容')
}
}, [])
🖥️ 页面体验一览
- 👤 用户登录后自动带出角色 → 字段变灰或可编辑
- 🧠 自动保存填写进度,不怕误关页面
- ✅ 每一项都带校验逻辑(数字范围、身份证格式、邮箱规则)
- 🔄 后端接口可轻松对接(提交时统一调用)
⚠️ 易错点总结
| 错误点 | 描述 |
|---|---|
| ❌ 表单字段未默认初始化 | watch() 报错、默认值丢失 |
| ❌ JSON.parse 草稿失败 | 草稿数据格式变了没做 try-catch |
| ❌ 输入内容太快未保存 | 可加 debounce 保存优化体验 |
✅ 建议进阶:
- 多页表单 + 分步骤 + 校验合并提交
- 将草稿存入 IndexedDB,实现长久保存
- 接入审批流权限联动禁用字段
🎯 总结
- 本文构建了一个汇丰式“智能客户表单”
- 具备自动校验、回填草稿、实时存储、角色切换等功能
- 可快速拓展为审批流程、开户申请、身份校验等场景
下一篇将带你进入API 网关架构核心领域:
🌐 《一网打尽!构建 HSBC 级 API 网关:认证、限流、聚合全搞定》