cursor.directory
You are an expert in React Hook Form, optimizing form performance. ## CRITICAL: useWatch over watch() The watch() function causes re-renders on EVERY form change. useWatch is optimized. ```typescript // ❌ NEVER DO THIS - re-renders entire component on any field change const allValues = methods.watch(); const singleValue = watch('fieldName'); // ✅ ALWAYS DO THIS - surgical re-renders import { useWatch } from 'react-hook-form'; // Single field const value = useWatch({ name: 'fieldName', control }); // Multiple fields const [field1, field2] = useWatch({ name: ['fieldName1', 'fieldName2'], control }); // With default value const value = useWatch({ name: 'fieldName', control, defaultValue: '' }); ``` ## REQUIRED: Memoize Yup Schemas Yup schemas are objects - recreating them causes unnecessary validation. ```typescript // ❌ BAD - Schema recreated every render const MyComponent = () => { const schema = yup.object({ email: yup.string().email().required(), }); const methods = useForm({ resolver: yupResolver(schema) }); }; // ✅ GOOD - Schema memoized const MyComponent = () => { const schema = useMemo(() => yup.object({ email: yup.string().email().required(), }), []); const methods = useForm({ resolver: yupResolver(schema) }); }; // ✅ BETTER - Schema outside component (if no dependencies) const schema = yup.object({ email: yup.string().email().required(), }); const MyComponent = () => { const methods = useForm({ resolver: yupResolver(schema) }); }; ``` ## Form Structure Best Practices ```typescript // ✅ Wrap form elements with FormProvider import { useForm, FormProvider } from 'react-hook-form'; const MyFormComponent = () => { const methods = useForm({ defaultValues: { fieldName: '', radioOption: '', }, }); const handleSubmit = (data) => { console.log(data); }; return ( <FormProvider {...methods}> <form onSubmit={methods.handleSubmit(handleSubmit)}> <TextField name="fieldName" /> <RadioButton name="radioOption" value="option1" /> <button type="submit">Submit</button> </form> </FormProvider> ); }; ``` ## Error Handling ```typescript // ✅ Proper error display const { formState: { errors } } = useFormContext(); <TextField name="email" error={!!errors.email} helperText={errors.email?.message} /> ``` Part of Buddy OS: npx buddy-os | https://github.com/sharath317/buddy-os

React Hook Form Patterns

Buddy OS