install
source · Clone the upstream repo
git clone https://github.com/ComeOnOliver/skillshub
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/TerminalSkills/skills/formik" ~/.claude/skills/comeonoliver-skillshub-formik && rm -rf "$T"
manifest:
skills/TerminalSkills/skills/formik/SKILL.mdsource content
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.
in onSubmit handles server-side validation errors (duplicate email, etc.).setErrors
only shows after field is touched — good UX by default.<ErrorMessage>- For large forms, use
when initial values come from API.enableReinitialize