如何用Formik和Yup实现ErrorMessage组件定时自动隐藏?
解决Formik ErrorMessage自动隐藏的问题
你的代码主要存在两个问题:
- 初始
errorVisible设为true,导致页面一加载就错误显示提示,不符合正常交互逻辑 - 仅在提交流程里控制错误显示,未关联Formik自身的错误状态,验证触发的错误无法自动隐藏
以下是修正后的实现方案:
核心思路
- 监听Formik的
errors与touched状态变化,当输入框触碰后出现错误时,自动显示提示并启动隐藏定时器 - 用
useRef存储定时器ID,在错误状态更新或组件卸载时清理旧定时器,避免内存泄漏 - 初始
errorVisible设为false,确保页面加载时无错误提示
修改后的完整代码
import { useState, useEffect, useRef } from 'react'; import { Formik, Form, Field, ErrorMessage } from 'formik'; import * as Yup from 'yup'; const validationSchema = Yup.object().shape({ inputField: Yup.string().required('Provide a search term.') }) function Hero() { const [errorVisible, setErrorVisible] = useState(false); const timerRef = useRef(null); // 保存定时器ID,用于清理 return ( <> <section className='hero hero__background' style={{ backgroundImage: `url(${background})` }}> <div className='container-u d-flex flex-column justify-content-center h-100'> <div className='hero__info'> <h2 className='text-white'>Learn Something New</h2> <p className='text-white'>All courses at $15</p> <Formik initialValues={{ inputField: '' }} validationSchema={validationSchema} onSubmit={async (values, { setSubmitting }) => { // 模拟API调用 setTimeout(() => { setSubmitting(false); }, 3000); }} > {({ errors, touched }) => { // 监听输入框的错误与触碰状态变化 useEffect(() => { // 只有用户触碰过输入框且存在错误时,才显示提示 if (errors.inputField && touched.inputField) { setErrorVisible(true); // 清理之前的定时器,避免重复触发 if (timerRef.current) clearTimeout(timerRef.current); // 3秒后自动隐藏错误提示 timerRef.current = setTimeout(() => { setErrorVisible(false); }, 3000); } else { setErrorVisible(false); } // 组件卸载时清理定时器 return () => { if (timerRef.current) clearTimeout(timerRef.current); }; }, [errors.inputField, touched.inputField]); return ( <Form className='hero__form'> <Field type="text" name="inputField" className="hero__input" /> {errorVisible && <ErrorMessage name='inputField' component="div" className='text-white text-uppercase fw-bold' />} <button style={{ backgroundImage: `url(${search})` }} className='hero__button' type='submit' /> </Form> ); }} </Formik> </div> </div> </section> </> ) }
关键说明
- 结合
errors和touched判断显示时机,避免用户未操作就弹出错误提示,更符合表单交互习惯 - 每次启动新定时器前清理旧的,防止多个定时器叠加导致提示提前或延迟隐藏
- 提交流程不再手动控制错误显示,完全依托Formik的验证机制,逻辑更简洁清晰
内容的提问来源于stack exchange,提问作者Gerardo J. Cruz
相关产品推荐
相关产品推荐

