用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/Dev-Toolbelt/dev-team-agents --skill form-handling命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
基于 SOC 职业分类
正在显示 SKILL.md
| name | form-handling |
| description | Form design — state, validation, error feedback. Framework-agnostic. |
Before writing any form code, check for an existing library:
| Signal | Library |
|---|---|
react-hook-form, useForm, register, Controller | React Hook Form |
formik, useFormik, <Formik> | Formik |
vee-validate, useField, useForm (Vue) | VeeValidate |
@angular/forms, FormBuilder, FormGroup, ReactiveFormsModule | Angular Reactive Forms |
zod, yup, valibot imports alongside form code | Schema validation library |
If no library is detected: useState per field is acceptable for forms with 1–3 fields. For anything larger, recommend adopting the project's preferred library before building.
Always bind input value to state and update state on change. Uncontrolled inputs (ref-only) are acceptable only for file inputs or third-party widgets that require direct DOM access.
| Trigger | When to use |
|---|---|
onBlur | Default for most fields — validates after the user leaves the field |
onChange | Use only after the first submission attempt, or for fields with instant feedback (password strength) |
onSubmit | Always run a full validation pass on submit, regardless of field-level validation |
Never validate onChange from the first keystroke on empty fields — it creates errors before the user has had a chance to type.
Define validation rules in a single schema (Zod, Yup, Valibot, or equivalent) rather than scattered if statements in handlers. The schema is the single source of truth for what constitutes valid data.
// good — rules live in one place, reusable on the server too
const orderSchema = z.object({
quantity: z.number().min(1).max(999),
email: z.string().email(),
})
aria-describedby (the field's id matches the error element's id)double-submission prevention in the agent)reset() must restore every field to its initial value, not just clear them to emptyregister over Controller for native inputs — less overheadController for third-party components (date pickers, select libraries)mode: 'onBlur' as the default validation triggerresolver (zod, yup) to keep validation out of the componentvalidationSchema with Yup rather than the validate function for complex formssetFieldValue inside onChange handlers — use Formik's handleChange to avoid double rendersenableReinitialize should be false by default; set to true only when the form must reflect external data changesdefineRule + configure globally for shared rules; use inline rules only for one-off caseszod via @vee-validate/zod for schema-first validationuseForm + useField (Composition API) is preferred over the Options API component approachFormBuilder — never instantiate FormGroup / FormControl manuallyFormControl definition, not in the templateupdateOn: 'blur' on controls that should validate after focus lossAbstractControl.statusChanges is the right hook for cross-field dependent validation — avoid manual valueChanges hacks| Anti-Pattern | Problem |
|---|---|
| Validation logic duplicated in component and service | Single source of truth broken; rules drift apart |
| Showing all errors before the user interacts | Hostile UX — validate progressively |
| Resetting only visible fields on submit | Hidden state leaks into the next submission |
Calling event.preventDefault() manually and then forgetting to handle errors | Leaves the form in a broken state on failure |
| Storing form state in a global store | Forms are transient UI state — keep them local |
any type for form values | Defeats the purpose of schema validation |