[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6EF1P9KCP8ZW398X609XPA6":3,"skill-same:01M6EF1P9KCP8ZW398X609XPA6":45},{"skillNo":4,"name":5,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":15,"categories":16,"keywords":17,"publishedAt":18,"linkOnly":19,"markdownContent":20,"markdownBody":20,"frontMatter":21,"refName":22,"commitSha":23,"skillDirectory":24,"forksCount":25,"repositoryHtmlUrl":26,"repositoryHomepageUrl":27,"ownerHtmlUrl":28,"ownerBlogUrl":6,"ownerDescription":29,"updatedAt":30,"install":31,"resources":44},"01M6EF1P9KCP8ZW398X609XPA6","formik",null,"ComeOnOliver\u002Fskillshub","ComeOnOliver","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F43215937?v=4","01M6E5JNFECJAAVFE0W7SMWWD2","Haoran Shu","01M6E5JNNDQS7AJZDYFQ8TPZCK",67,"MIT","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FTerminalSkills\u002Fskills\u002Fformik\u002FSKILL.md",[],[5],"2026-11-10 10:12:30",false,"# Formik\n\n## Overview\n\nFormik manages form state in React — values, errors, touched fields, submission. Integrates with Yup\u002FZod for schema validation. Handles complex forms (multi-step, dynamic fields, arrays) without Redux or complex state management.\n\n## Instructions\n\n### Step 1: Basic Form\n\n```tsx\nimport { Formik, Form, Field, ErrorMessage } from 'formik'\nimport * as Yup from 'yup'\n\nconst SignupSchema = Yup.object({\n  name: Yup.string().min(2).required('Name is required'),\n  email: Yup.string().email('Invalid email').required('Email is required'),\n  password: Yup.string().min(8, 'At least 8 characters').required('Password is required'),\n})\n\nfunction SignupForm() {\n  return (\n    \u003CFormik\n      initialValues={{ name: '', email: '', password: '' }}\n      validationSchema={SignupSchema}\n      onSubmit={async (values, { setSubmitting, setErrors }) => {\n        try {\n          await api.signup(values)\n        } catch (err) {\n          setErrors({ email: 'Email already registered' })\n        } finally {\n          setSubmitting(false)\n        }\n      }}\n    >\n      {({ isSubmitting }) => (\n        \u003CForm>\n          \u003CField name=\"name\" placeholder=\"Name\" \u002F>\n          \u003CErrorMessage name=\"name\" component=\"span\" className=\"error\" \u002F>\n\n          \u003CField name=\"email\" type=\"email\" placeholder=\"Email\" \u002F>\n          \u003CErrorMessage name=\"email\" component=\"span\" className=\"error\" \u002F>\n\n          \u003CField name=\"password\" type=\"password\" placeholder=\"Password\" \u002F>\n          \u003CErrorMessage name=\"password\" component=\"span\" className=\"error\" \u002F>\n\n          \u003Cbutton type=\"submit\" disabled={isSubmitting}>Sign Up\u003C\u002Fbutton>\n        \u003C\u002FForm>\n      )}\n    \u003C\u002FFormik>\n  )\n}\n```\n\n### Step 2: Dynamic Field Arrays\n\n```tsx\nimport { FieldArray } from 'formik'\n\nfunction TeamForm() {\n  return (\n    \u003CFormik initialValues={{ members: [{ name: '', role: '' }] }} onSubmit={handleSubmit}>\n      {({ values }) => (\n        \u003CForm>\n          \u003CFieldArray name=\"members\">\n            {({ push, remove }) => (\n              \u003C>\n                {values.members.map((_, i) => (\n                  \u003Cdiv key={i}>\n                    \u003CField name={`members.${i}.name`} placeholder=\"Name\" \u002F>\n                    \u003CField name={`members.${i}.role`} as=\"select\">\n                      \u003Coption value=\"\">Select role\u003C\u002Foption>\n                      \u003Coption value=\"admin\">Admin\u003C\u002Foption>\n                      \u003Coption value=\"member\">Member\u003C\u002Foption>\n                    \u003C\u002FField>\n                    \u003Cbutton type=\"button\" onClick={() => remove(i)}>Remove\u003C\u002Fbutton>\n                  \u003C\u002Fdiv>\n                ))}\n                \u003Cbutton type=\"button\" onClick={() => push({ name: '', role: '' })}>\n                  Add Member\n                \u003C\u002Fbutton>\n              \u003C\u002F>\n            )}\n          \u003C\u002FFieldArray>\n        \u003C\u002FForm>\n      )}\n    \u003C\u002FFormik>\n  )\n}\n```\n\n## Guidelines\n\n- For new projects, consider react-hook-form (less re-renders). Formik is still solid for existing projects.\n- Use schema validation (Yup\u002FZod) instead of manual validate functions.\n- `setErrors` in onSubmit handles server-side validation errors (duplicate email, etc.).\n- `\u003CErrorMessage>` only shows after field is touched — good UX by default.\n- For large forms, use `enableReinitialize` when initial values come from API.\n",{},"main","def8531e65114c0fca8fb8551c1871ee0eed705c","skills\u002FTerminalSkills\u002Fskills\u002Fformik",24,"https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub","https:\u002F\u002Fskillshub.wtf","https:\u002F\u002Fgithub.com\u002FComeOnOliver","AI & Blockchain Engineer\r\n","2026-06-24 22:07:19",{"source":7,"skillName":5,"commands":32,"prompt":42,"zipAvailable":43},[33,36,39],{"tool":34,"command":35},"npx","npx skills add ComeOnOliver\u002Fskillshub --skill formik",{"tool":37,"command":38},"bunx","bunx skills add ComeOnOliver\u002Fskillshub --skill formik",{"tool":40,"command":41},"pnpm","pnpm dlx skills add ComeOnOliver\u002Fskillshub --skill formik","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002FTerminalSkills\u002Fskills\u002Fformik\u002FSKILL.md",true,[],[46,60,70,79,85,92],{"skillNo":47,"name":48,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":49,"categories":50,"keywords":56,"publishedAt":18},"01M6FKJN13GMG4KY57J3QD8GY5","model-hierarchy-skill","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzscole\u002Fmodel-hierarchy-skill\u002Fmodel-hierarchy-skill\u002FSKILL.md",[51],{"categoryNo":52,"categoryName":53,"taxonomyType":54,"taxonomyTypeDesc":55},"01JBSEEDCAT000000000000023","Skill与智能体开发","SCENARIO","使用场景",[57,58,59],"model","model hierarchy","model hierarchy skill",{"skillNo":61,"name":62,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":63,"categories":64,"keywords":66,"publishedAt":18},"01M6FKJJJ6GCAMR4PPPRD12M5X","zoom-mcp","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-mcp\u002FSKILL.md",[65],{"categoryNo":52,"categoryName":53,"taxonomyType":54,"taxonomyTypeDesc":55},[67,68,69],"MCP","zoom","zoom mcp",{"skillNo":71,"name":72,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":73,"categories":74,"keywords":75,"publishedAt":18},"01M6FKJE3KYT3KPEZMEEHYKA6K","zoom-apps-sdk","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fzoom-apps-sdk\u002FSKILL.md",[],[76,77,78,68],"sdk","zoom apps sdk","apps",{"skillNo":80,"name":81,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":82,"categories":83,"keywords":84,"publishedAt":18},"01M6FKJ9EDH9Q5VWDF8HAJRSP0","windows","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwindows\u002FSKILL.md",[],[81],{"skillNo":86,"name":87,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":88,"categories":89,"keywords":91,"publishedAt":18},"01M6FKJ666BEEFC3AE9GJ72Q93","whiteboard","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwhiteboard\u002FSKILL.md",[90],{"categoryNo":52,"categoryName":53,"taxonomyType":54,"taxonomyTypeDesc":55},[87],{"skillNo":93,"name":94,"nameZh":6,"description":6,"descriptionZh":6,"repositoryFullName":7,"ownerLogin":8,"ownerAvatarUrl":9,"ownerAccountNo":10,"ownerDisplayName":11,"repositoryNo":12,"starsCount":13,"licenseSpdxId":14,"licenseFileUrl":6,"sourceHtmlUrl":95,"categories":96,"keywords":97,"publishedAt":18},"01M6FKJ21WFCDGTJQ2Q91T9DVW","websockets","https:\u002F\u002Fgithub.com\u002FComeOnOliver\u002Fskillshub\u002Fblob\u002Fmain\u002Fskills\u002Fzoom\u002Fskills\u002Fwebsockets\u002FSKILL.md",[],[94]]