> formik
Build forms in React with Formik. Use when creating complex forms with validation, multi-step forms, dynamic form fields, or handling form submission with error states.
curl "https://skillshub.wtf/TerminalSkills/skills/formik?format=md"Formik
Overview
Formik manages form state in React — values, errors, touched fields, submission. Integrates with Yup/Zod for schema validation. Handles complex forms (multi-step, dynamic fields, arrays) without Redux or complex state management.
Instructions
Step 1: Basic Form
import { Formik, Form, Field, ErrorMessage } from 'formik'
import * as Yup from 'yup'
const SignupSchema = Yup.object({
name: Yup.string().min(2).required('Name is required'),
email: Yup.string().email('Invalid email').required('Email is required'),
password: Yup.string().min(8, 'At least 8 characters').required('Password is required'),
})
function SignupForm() {
return (
<Formik
initialValues={{ name: '', email: '', password: '' }}
validationSchema={SignupSchema}
onSubmit={async (values, { setSubmitting, setErrors }) => {
try {
await api.signup(values)
} catch (err) {
setErrors({ email: 'Email already registered' })
} finally {
setSubmitting(false)
}
}}
>
{({ isSubmitting }) => (
<Form>
<Field name="name" placeholder="Name" />
<ErrorMessage name="name" component="span" className="error" />
<Field name="email" type="email" placeholder="Email" />
<ErrorMessage name="email" component="span" className="error" />
<Field name="password" type="password" placeholder="Password" />
<ErrorMessage name="password" component="span" className="error" />
<button type="submit" disabled={isSubmitting}>Sign Up</button>
</Form>
)}
</Formik>
)
}
Step 2: Dynamic Field Arrays
import { FieldArray } from 'formik'
function TeamForm() {
return (
<Formik initialValues={{ members: [{ name: '', role: '' }] }} onSubmit={handleSubmit}>
{({ values }) => (
<Form>
<FieldArray name="members">
{({ push, remove }) => (
<>
{values.members.map((_, i) => (
<div key={i}>
<Field name={`members.${i}.name`} placeholder="Name" />
<Field name={`members.${i}.role`} as="select">
<option value="">Select role</option>
<option value="admin">Admin</option>
<option value="member">Member</option>
</Field>
<button type="button" onClick={() => remove(i)}>Remove</button>
</div>
))}
<button type="button" onClick={() => push({ name: '', role: '' })}>
Add Member
</button>
</>
)}
</FieldArray>
</Form>
)}
</Formik>
)
}
Guidelines
- For new projects, consider react-hook-form (less re-renders). Formik is still solid for existing projects.
- Use schema validation (Yup/Zod) instead of manual validate functions.
setErrorsin onSubmit handles server-side validation errors (duplicate email, etc.).<ErrorMessage>only shows after field is touched — good UX by default.- For large forms, use
enableReinitializewhen initial values come from API.
> related_skills --same-repo
> zustand
You are an expert in Zustand, the small, fast, and scalable state management library for React. You help developers manage global state without boilerplate using Zustand's hook-based stores, selectors for performance, middleware (persist, devtools, immer), computed values, and async actions — replacing Redux complexity with a simple, un-opinionated API in under 1KB.
> zod
You are an expert in Zod, the TypeScript-first schema declaration and validation library. You help developers define schemas that validate data at runtime AND infer TypeScript types at compile time — eliminating the need to write types and validators separately. Used for API input validation, form validation, environment variables, config files, and any data boundary.
> xero-accounting
Integrate with the Xero accounting API to sync invoices, expenses, bank transactions, and contacts — and generate financial reports like P&L and balance sheet. Use when: connecting apps to Xero, automating bookkeeping workflows, syncing accounting data, or pulling financial reports programmatically.
> windsurf-rules
Configure Windsurf AI coding assistant with .windsurfrules and workspace rules. Use when: customizing Windsurf for a project, setting AI coding standards, creating team-shared Windsurf configurations, or tuning Cascade AI behavior.