1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
| const useForm = (initialValues, validationSchema) => { const [values, setValues] = useState(initialValues); const [errors, setErrors] = useState({}); const [isSubmitting, setIsSubmitting] = useState(false); const [touched, setTouched] = useState({});
const handleChange = (name, value) => { setValues(prev => ({ ...prev, [name]: value }));
if (touched[name]) { validateField(name, value); } };
const handleBlur = (name) => { setTouched(prev => ({ ...prev, [name]: true })); validateField(name, values[name]); };
const validateField = (name, value) => { if (validationSchema && validationSchema[name]) { try { validationSchema[name].validateSync(value); setErrors(prev => ({ ...prev, [name]: undefined })); } catch (error) { setErrors(prev => ({ ...prev, [name]: error.message })); } } };
const validateForm = () => { if (!validationSchema) return true;
try { validationSchema.validateSync(values, { abortEarly: false }); setErrors({}); return true; } catch (error) { const newErrors = {}; error.inner.forEach(err => { newErrors[err.path] = err.message; }); setErrors(newErrors); return false; } };
const handleSubmit = async (onSubmit) => { if (!validateForm()) return;
setIsSubmitting(true); try { await onSubmit(values); } finally { setIsSubmitting(false); } };
return { values, errors, touched, isSubmitting, handleChange, handleBlur, handleSubmit }; };
const ContactForm = () => { const validationSchema = { name: Yup.string().required('Name is required'), email: Yup.string().email('Invalid email').required('Email is required'), message: Yup.string().min(10, 'Message must be at least 10 characters') };
const { values, errors, handleChange, handleBlur, handleSubmit, isSubmitting } = useForm({ name: '', email: '', message: '' }, validationSchema);
return ( <form onSubmit={(e) => { e.preventDefault(); handleSubmit(async (formData) => { await submitContactForm(formData); }); }}> <input name="name" value={values.name} onChange={(e) => handleChange('name', e.target.value)} onBlur={() => handleBlur('name')} placeholder="Name" /> {errors.name && <span className="error">{errors.name}</span>}
<input name="email" value={values.email} onChange={(e) => handleChange('email', e.target.value)} onBlur={() => handleBlur('email')} placeholder="Email" /> {errors.email && <span className="error">{errors.email}</span>}
<textarea name="message" value={values.message} onChange={(e) => handleChange('message', e.target.value)} onBlur={() => handleBlur('message')} placeholder="Message" /> {errors.message && <span className="error">{errors.message}</span>}
<button type="submit" disabled={isSubmitting}> {isSubmitting ? 'Sending...' : 'Send Message'} </button> </form> ); };
|