在项目中用Formik处理表单的那些事与实用技巧总结
为什么我要对比这几个表单方案?
最近在做一个项目,涉及到复杂的表单逻辑。说实在的,表单这东西看似简单,但一复杂起来真是让人头疼。我之前用过Formik,感觉还不错,但这次需求有点特殊,想看看还有没有更适合的方案。于是我把几个常用的表单库(Formik、React Hook Form、原生表单)都拉出来溜了一圈,踩了不少坑,也总结了一些心得。
核心代码就这几行
先上代码吧,毕竟咱们搞前端的,代码最直观。这里我分别用Formik和React Hook Form写了一个简单的登录表单:
// Formik实现
import { useFormik } from 'formik';
const LoginForm = () => {
const formik = useFormik({
initialValues: { email: '', password: '' },
onSubmit: values => console.log(values),
});
return (
<form onSubmit={formik.handleSubmit}>
<input name="email" onChange={formik.handleChange} value={formik.values.email} />
<input name="password" onChange={formik.handleChange} value={formik.values.password} type="password" />
<button type="submit">登录</button>
</form>
);
};
// React Hook Form实现
import { useForm } from 'react-hook-form';
const LoginForm = () => {
const { register, handleSubmit } = useForm();
const onSubmit = data => console.log(data);
return (
<form onSubmit={handleSubmit(onSubmit)}>
<input {...register('email')} />
<input {...register('password')} type="password" />
<button type="submit">登录</button>
</form>
);
};
代码看起来都很简洁,对吧?但实际用起来,差别还挺大的。
谁更灵活?谁更省事?
从灵活性来说,我比较喜欢用React Hook Form。它的register方法直接绑定到原生DOM元素上,性能比Formik要好,因为它减少了不必要的重渲染。而且React Hook Form自带校验功能,不用再额外引入Yup这种库。
不过呢,React Hook Form的灵活性有时候反而是个坑。比如你想动态添加表单项,React Hook Form虽然支持,但得手动调用trigger或者重新注册字段,这点就比Formik麻烦了。我之前在一个动态问卷系统里踩过这个坑,折腾了半天才发现需要手动触发校验。
而Formik在这方面就很贴心,动态表单项直接通过状态管理就能搞定,完全不用操心底层细节。看场景,我一般选Formik来处理复杂表单。
性能对比:差距比我想象的大
说到性能,React Hook Form确实有优势。它用了非受控组件的方式,只有在用户输入时才会更新状态。而Formik是典型的受控组件模式,每次输入都会触发状态更新。
我在一个包含50个表单项的复杂表单里做了个测试,结果如下:
- Formik:每秒重渲染次数大约是20次
- React Hook Form:每秒重渲染次数只有3次左右
虽然React Hook Form性能更好,但我发现一个问题:当表单特别复杂时,React Hook Form的错误提示有时候会延迟一两帧才出现。用户体验上稍微差了点,但这可能是个体感受。
我的选型逻辑
综合下来,我的选型建议是这样的:
1. 如果表单比较简单:我会优先选择React Hook Form,代码量少,性能也好。
2. 如果表单复杂且动态性强:我会毫不犹豫选Formik,虽然性能差点,但开发效率高,坑也少。
3. 原生表单:除非项目要求非常轻量,不然我是不会用原生表单的,太繁琐了。
举个例子,前阵子做的一个CRM系统,里面有各种动态表单,我就选了Formik。虽然性能上稍微差点,但开发速度快,后期维护也方便。毕竟客户也不在乎那几毫秒的性能差距,对吧?
踩坑提醒:这三点一定注意
最后分享几个踩坑经验,给大家提个醒:
- React Hook Form的校验问题:如果你用了自定义组件,记得手动调用
ref注册,否则校验会失效。 - Formik的性能优化:如果表单很大,可以试试
shouldValidateOnChange选项,减少不必要的校验。 - 动态表单项的坑:无论是Formik还是React Hook Form,动态表单项都需要额外处理,别忘了监听字段变化。
以上是我的对比总结
总的来说,这两个库各有优劣,关键还是看需求场景。我个人更偏爱Formik,主要是因为它的API设计很符合直觉,写起来顺手。当然,React Hook Form也有自己的亮点,特别是在性能方面。
以上是我个人对这个表单方案的完整讲解,有更优的实现方式欢迎评论区交流。
