The watch() function causes re-renders on EVERY form change. useWatch is optimized.
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-osComprehensive .cursorrules file for Next.js 15 App Router projects with TypeScript, enforcing server components by default, proper use of "use client" directive, and App Router conventions.
Cursor rules for Python FastAPI projects enforcing async patterns, Pydantic v2 models, dependency injection, and proper error handling.
Rules for consistent React component development with TypeScript interfaces, proper hook patterns, and component composition.
Rules optimizing Cursor Agent mode behavior including multi-file editing context, session management, and autonomous task completion patterns.
Cursor rules for projects using Tailwind CSS with shadcn/ui component library, enforcing consistent utility class usage and component patterns.
Rules for Go backend services enforcing idiomatic Go patterns, proper error handling, and clean architecture conventions.