如何让Formik表单初始化时将所有字段的touched状态设为true
解决方案
你可以通过两种方式实现初始化时将所有字段的touched状态设为true,同时支持传入布尔值控制是否启用这个行为:
方法一:使用initialTouched属性直接初始化
Formik支持通过initialTouched配置项设置初始的touched状态。你可以根据initialValues生成一个所有字段值为true的对象,再配合传入的布尔值开关来决定是否启用:
// 生成所有字段touched为true的对象 const getInitialTouched = (values, enable) => { if (!enable) return {}; return Object.fromEntries( Object.keys(values).map(key => [key, true]) ); }; // 在组件中使用 <Formik key={key} initialValues={initialValues} // 根据开关生成initialTouched initialTouched={getInitialTouched(initialValues, showErrorsOnMount)} validationSchema={validationSchema} validateOnMount onSubmit={async values => {}} > <form> {children} </form> </Formik>
方法二:通过Formik上下文手动设置touched
如果需要更灵活的控制(比如依赖其他状态),可以在Formik的子组件中利用useFormikContext钩子获取Formik实例,在组件挂载时调用setTouched方法:
import { useFormikContext, useEffect } from 'formik'; // 封装一个控制组件,放在Formik内部 const InitializeTouched = ({ enable }) => { const { setTouched, values } = useFormikContext(); useEffect(() => { if (enable) { // 生成所有字段touched为true的对象并设置 const allTouched = Object.fromEntries( Object.keys(values).map(key => [key, true]) ); setTouched(allTouched); } }, [enable, setTouched, values]); return null; }; // 修改你的Formik组件 <Formik key={key} initialValues={initialValues} validationSchema={validationSchema} validateOnMount onSubmit={async values => {}} > <form> {/* 加入这个控制组件,传入你的布尔开关 */} <InitializeTouched enable={showErrorsOnMount} /> {children} </form> </Formik>
两种方法都能实现需求:方法一更简洁,适合静态初始化;方法二更灵活,适合需要动态判断的场景。记得确保validateOnMount已经开启,这样Formik会在挂载时就执行校验,结合touched为true的状态,就能直接显示错误信息了。
内容的提问来源于stack exchange,提问作者tilly
相关产品推荐
相关产品推荐

