关于表单,别做工具库舔狗

别做工具库舔狗,我喂自己袋盐 ------------于晏 🤦‍♂️

聊聊表单方案的选择:原生表单和表单库到底该怎么选?可能对刚入门的兄弟们有点用,老鸟轻喷🤦‍♂️🤦‍♂️🤦‍♂️,为什么写这个低级得玩意,纯粹是因为需求变少,给自己找点事干,然后就是想加强一点对一些代码得自我思考能力,思考是思考了,但不多🤐


背景 😊

最近写了个账号删除表单,字段不多:邮箱、删除原因(单选)、两个确认复选框。验证逻辑也简单:必填项检查 + 邮箱格式校验。一开始纠结要不要用 React Hook Form 这类表单库,最后还是用了原生表单 + useState 实现。

倒不是说表单库不好,只是稍微思考了一下:我的删号这个场景入口在app,然后app点击得时候通过我给出得地址带过来加密得用户userid+请求token,然后我这边解析出userid和token+表单字段提交给后端,然后其实我的项目本身做的就是一些app内嵌h5功能,分享,协议,这次加了个邀请,然后目前没有涉及到很复杂得表单,用第三方得表单库,我认为是冗余得(这个纯看自己了,冗余不冗余也不知道各位彦祖怎么看),这种场景其实很常见,例:当你跟面试官介绍你自己使用得工具库时,你使用echartsreact-echarts ,然后react-reduxzustand得选择,为什么这样选择?理由是什么?业务决定?又或者性能?


为什么要纠结这个? 🤔

刚学 React 的时候总觉得不用个啥库就不专业,写表单必须上 React Hook Form 或者 AntD Form。后来写多了才发现,简单场景下强行用库反而会:

  • 增加依赖体积(哪怕 10KB 也是额外加载)
  • 多一层学习成本(register、handleSubmit 这些 API 得记)
  • 调试变复杂(库的内部状态偶尔会让人摸不着头脑)

看看我这个删除账号表单的核心逻辑:

tsx

ini 复制代码
// 状态管理
const [email, setEmail] = useState("");
const [reason, setReason] = useState("");
const [confirm1, setConfirm1] = useState(false);
const [confirm2, setConfirm2] = useState(false);
const [errors, setErrors] = useState({
  email: "",
  reason: "",
  confirm1: "",
  confirm2: "",
});

// 验证逻辑
const handleSubmit = (e: React.FormEvent) => {
  e.preventDefault();
  const newErrors = { email: "", reason: "", confirm1: "", confirm2: "" };
  let valid = true;

  if (email && !/^[\w.-]+@[\w.-]+.\w+$/.test(email)) {
    newErrors.email = "Invalid email format";
    valid = false;
  }
  if (!reason) newErrors.reason = "Please tell us why you're leaving";
  if (!confirm1) newErrors.confirm1 = "Required confirmation";
  if (!confirm2) newErrors.confirm2 = "Required confirmation";

  setErrors(newErrors);
  if (valid) setShowModal(true);
};

这段代码虽然简单,但胜在:

  • 零依赖,移植性强
  • 逻辑直观,新手也能看懂
  • 样式完全自定义(那个渐变色背景和自定义复选框轻松实现)

如果换成 React Hook Form,代码量可能差不多甚至更多,反而显得冗余。


什么时候该用表单库? 🤔

但如果遇到下面这些场景,我肯定会毫不犹豫用表单库:

  1. 字段数量多(比如注册表单有 10 + 字段)

    • 原生需要写 N 个 useState 和 onChange,重复劳动
    • 表单库一行 register 就能搞定
  2. 复杂验证(跨字段校验、异步校验)

    • 比如 "密码强度校验"、"两次密码一致"
    • 用 Zod 配合 React Hook Form,声明式写法秒杀手动 if-else
  3. 动态表单(动态添加 / 删除字段组)

    • 比如 "紧急联系人" 可以添加多个
    • 原生需要手动管理数组状态,表单库自带数组处理

看看这种场景下的代码对比(简化版):

jsx

ini 复制代码
// 原生实现跨字段验证(确认密码)
const [password, setPassword] = useState('');
const [confirmPwd, setConfirmPwd] = useState('');
const [errors, setErrors] = useState({});

const validate = () => {
  const newErrors = {};
  if (password !== confirmPwd) {
    newErrors.confirmPwd = "两次密码不一致";
  }
  setErrors(newErrors);
  return Object.keys(newErrors).length === 0;
};

// React Hook Form + Zod实现
const schema = z.object({
  password: z.string().min(6),
  confirmPwd: z.string(),
}).refine(data => data.password === data.confirmPwd, {
  message: "两次密码不一致",
  path: ["confirmPwd"],
});

const { register, formState: { errors } } = useForm({
  resolver: zodResolver(schema)
});

明显能感觉到复杂场景下表单库的优势 ------ 代码更简洁,逻辑更清晰。


我的选择标准(实战总结)

  1. 先看字段数量

    • ≤5 个字段:优先原生(除非有特殊需求)
    • ≥6 个字段:考虑表单库
  2. 再看验证复杂度

    • 只有必填 / 简单格式校验:原生足够
    • 有跨字段 / 异步校验:必须表单库
  3. 最后看样式需求

    • 高度定制化设计:原生 + CSS(避免 UI 库样式冲突)
    • 常规设计:可以用表单库 + UI 组件(如 MUI、Shadcn)
  4. tips🤔🤷‍♂️

    • 后台系统,复杂页面提交无脑工具库
    • 简单表单,涉及到较少表单逻辑原生

回到我那个删除账号表单:

  • 4 个字段(邮箱、原因、两个复选框)
  • 验证只有必填和邮箱格式
  • 样式有渐变背景、自定义复选框
  • 结论:原生实现是最优解 😴

我的表单展示

常见误区

  1. 认为用表单库就是高级

    • 其实过度使用库会导致代码冗余,增加维护成本
  2. 原生表单一定比库性能好

    • 复杂表单场景下,表单库(如 React Hook Form 基于非受控组件)性能反而更好
  3. 样式和逻辑必须绑定

    • 最好分开处理:用 Tailwind/CSS Modules 写样式,用状态管理工具处理逻辑
  4. ~~ 追求一刀切方案~~ (思考)

    • 项目里完全可以混合使用:简单表单用原生,复杂表单用库 (彦祖们怎么看这个问题,我其实是喜欢统一)

最后想说的

写代码和做事一样,讲究 "恰到好处"。不用盲目追求新技术新工具,也不能固守旧方法不变。

判断一个方案好不好,不是看它多先进,而是看它能不能用最少的代码解决问题,同时保证可维护性和用户体验。

就像我这个删除账号表单,用原生实现可能在某些人看来不够 "高级",但对当前场景来说,它就是最合适的方案。

从一开始纠结用不用库,到分析场景找到最优解,这个过程本身比结论更有价值吧。毕竟编程这东西,没有绝对的对错,只有适合不适合🤐🤐🤐

相关推荐
空白格972 小时前
Android插件化开发
前端
风中凌乱的L2 小时前
vue canvas标注
前端·vue.js·canvas
拉不动的猪2 小时前
什么是二义性,实际项目中又有哪些应用
前端·javascript·面试
海云前端12 小时前
Webpack打包提速95%实战:从20秒到1.5秒的优化技巧
前端
烟袅2 小时前
LeetCode 142:环形链表 II —— 快慢指针定位环的起点(JavaScript)
前端·javascript·算法
梦6502 小时前
什么是react?
前端·react.js·前端框架
zhougl9962 小时前
cookie、session、token、JWT(JSON Web Token)
前端·json
Ryan今天学习了吗2 小时前
💥不说废话,带你上手使用 qiankun 微前端并深入理解原理!
前端·javascript·架构
高端章鱼哥2 小时前
前端新人最怕的“居中问题”,八种CSS实现居中的方法一次搞懂!
前端