Token导航 LogoToken导航

Agent Skill · 前端设计

react-hook-form(React hook form ORM)

用于辅助 API 设计、接口文档、请求响应结构和服务集成说明。它适合让 Agent 梳理 endpoint、生成 OpenAPI 草稿、检查字段命名、整理错误码或辅助前后端联调。使用时需要确认真实业务语义、鉴权方式、分页和错误处理规则;涉及生成接口文档时,应避免凭空补字段,最好从现有代码、schema 或接口样例中提取事实。

react-hook-form 是前端设计类 Agent Skill,可用宿主为 Codex、Claude、Cursor、Gemini CLI,通过GitHub 仓库获取,权限为需要联网;许可证为 MIT,第三方扫描已通过,按安装量在前端设计类的 10,216 个 Skill 里排第 9,098。

总安装 238周安装 10GitHub Stars 2下载 83核验 2026-05-01

安装说明

本站只整理中文说明,不托管安装包,也不代用户安装。
GitHub
许可证
MIT

安装方式

通过对话安装

复制提示词发给支持本地命令或 Skills 的 AI 助手,先确认命令和权限,再让它执行。

请帮我安装这个 Agent Skill:react-hook-form(React hook form ORM)
来源仓库:https://github.com/slanycukr/riot-api-project
仓库路径:skills/react-hook-form
安装命令:
npx skills add https://github.com/slanycukr/riot-api-project --skill react-hook-form
安装前请先检查当前环境是否支持对应 CLI,并向我确认将要执行的命令、安装目录、联网范围和文件读写权限;确认后再执行。

命令行安装

复制命令到本机终端执行。不同来源提供的安装方式可能略有差异;本站展示可直接复制的安装命令,安装前请核对来源页面。

skills.shnpx skills
npx skills add https://github.com/slanycukr/riot-api-project --skill react-hook-form

这个 Skill 是做什么的

前端设计类 Skill 关注页面结构、视觉规范和组件写法,输出通常是可运行的界面代码。

用于辅助 API 设计、接口文档、请求响应结构和服务集成说明。适合让 Agent 梳理 endpoint、生成 OpenAPI 草稿、检查字段命名或辅助前后端联调。使用时需要确认真实业务语义、鉴权方式、分页和错误处理规则。涉及生成接口文档时,应避免凭空补字段,最好从现有代码、schema 或接口样例中提取事实。

安装前建议确认权限范围和维护状态,以及是否会触发联网或文件读写操作。

来源仓库内路径:skills/react-hook-form

上手步骤

4 步
  1. 1

    确认自己的宿主工具

    公开资料标注支持 Codex、Claude、Cursor、Gemini CLI;先确认自己用的是其中之一,再按对应工具的 Skills 目录放置。

  2. 2

    拿到安装命令

    可以直接复制的命令是 npx skills add https://github.com/slanycukr/riot-api-project --skill react-hook-…;命令里的占位符换成自己的路径或密钥再执行。

  3. 3

    安装后重启宿主

    命令执行完要完全退出宿主工具再打开,让新装的 Skill 被重新扫描到,否则列表里可能看不到。

  4. 4

    按最小权限试用

    它需要需要联网,先在测试目录或测试账号里跑,确认没问题再放到正式项目。

常见问题

6 条

react-hook-form 怎么安装?

在终端执行 npx skills add https://github.com/slanycukr/riot-api-project --skill react-hook-form。装完完全退出宿主工具再打开,让它重新扫描本地 Skill。

react-hook-form 支持哪些 AI 工具?

公开资料标注支持 Codex、Claude、Cursor、Gemini CLI。其他工具只要能读取本地 Skill 目录,一般也能手动放进去,但要自己确认触发方式是否一致。

react-hook-form 需要什么权限?

权限级别是需要联网。该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

react-hook-form 是免费的吗?

来源标注的许可证是 MIT。本站不代收任何费用,也不托管安装包;能否商用、要不要署名,以许可证原文为准。

react-hook-form 用的人多吗?

公开数据是累计安装 238 次,近一周安装 10 次,下载 83 次,GitHub 2 星。这些数字来自第三方目录统计,只能当作热度参考,不代表质量或安全性。

react-hook-form 安全吗?

第三方扫描结果为通过,但这只覆盖已知的静态检查项,不能替代自己读一遍源码和安装命令。

值得选的地方和要先想清楚的地方

值得选的地方

  • 同时适配 4 种工具,换客户端不用重新找替代品。
  • 3 个目录同时收录,说明这个 Skill 流传比较广。
  • 许可证明确为 MIT,商用和分发边界好判断。
  • 第三方扫描已通过,常见的高风险行为没有命中。

先想清楚的地方

  • 第三方目录整理,版本更新和行为细节以来源仓库为准。

适不适合你

更适合

  • 已经在用 Codex,想直接扩展它能力的人。
  • 需要处理前端设计类任务、又不想每次都手写提示词的人。
  • 需要许可证清楚、并且有第三方扫描结果的团队项目。

不太适合

  • 需要厂商级技术支持和 SLA 的生产系统。

前端设计类 Skill 对比

6 个同类
Skill总安装GitHub 星权限许可证扫描
frontend-design

前端设计 · Codex、Claude

8,823,360126,072只读MIT通过
vercel-composition-patterns

Vercel 组合模式 · Codex、Claude

3,858,81625,893需要联网MIT通过
vercel-react-native-skills

Vercel React native skills 前端 · Codex、Claude

2,468,66425,878只读MIT通过
adapt

adapt 搜索 · Codex、Claude

2,027,04023,125操作浏览器未明确通过
bolder

bolder 分析 · Codex、Claude

2,004,28823,130只读未明确通过
react-hook-form

React hook form ORM · 本页

2382需要联网MIT通过

按安装量取同分类前几名;数字来自第三方目录统计,只作热度参考,不代表质量结论。

SKILL.md 原文

React Hook Form

Quick Start

Basic Form

import { useForm } from "react-hook-form";

function BasicForm() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm();

  const onSubmit = (data) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("firstName")} />
      <input {...register("lastName", { required: "Last name is required" })} />
      {errors.lastName && <p>{errors.lastName.message}</p>}
      <input {...register("age", { pattern: /\d+/ })} />
      {errors.age && <p>Please enter number for age.</p>}
      <input type="submit" />
    </form>
  );
}

Form with Default Values

import { useForm } from "react-hook-form";

function FormWithDefaults() {
  const { register, handleSubmit } = useForm({
    defaultValues: {
      firstName: "John",
      lastName: "Doe",
      email: "john@example.com",
    },
  });

  const onSubmit = (data) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("firstName")} />
      <input {...register("lastName")} />
      <input {...register("email")} />
      <button type="submit">Submit</button>
    </form>
  );
}

Common Patterns

Form Validation

import { useForm } from "react-hook-form";

function ValidationExample() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm();

  const onSubmit = (data) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        {...register("username", {
          required: "Username is required",
          minLength: {
            value: 3,
            message: "Username must be at least 3 characters",
          },
          maxLength: {
            value: 20,
            message: "Username must be less than 20 characters",
          },
        })}
      />
      {errors.username && <span>{errors.username.message}</span>}

      <input
        {...register("email", {
          required: "Email is required",
          pattern: {
            value: /^\S+@\S+$/i,
            message: "Invalid email format",
          },
        })}
      />
      {errors.email && <span>{errors.email.message}</span>}

      <button type="submit">Submit</button>
    </form>
  );
}

Password Confirmation

import { useForm } from "react-hook-form";

function PasswordForm() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm();

  const onSubmit = (data) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        type="password"
        {...register("password", {
          required: "Password is required",
          minLength: {
            value: 8,
            message: "Password must be at least 8 characters",
          },
        })}
      />
      {errors.password && <span>{errors.password.message}</span>}

      <input
        type="password"
        {...register("confirmPassword", {
          required: "Please confirm your password",
          validate: (value, formValues) =>
            value === formValues.password || "Passwords do not match",
        })}
      />
      {errors.confirmPassword && <span>{errors.confirmPassword.message}</span>}

      <button type="submit">Submit</button>
    </form>
  );
}

Using Controller for Custom Components

import { useForm, Controller } from "react-hook-form";
import Select from "react-select";

function CustomInputForm() {
  const { handleSubmit, control } = useForm();

  const options = [
    { value: "chocolate", label: "Chocolate" },
    { value: "strawberry", label: "Strawberry" },
    { value: "vanilla", label: "Vanilla" },
  ];

  const onSubmit = (data) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <Controller
        name="flavor"
        control={control}
        rules={{ required: "Please select a flavor" }}
        render={({ field, fieldState: { error } }) => (
          <div>
            <Select {...field} options={options} />
            {error && <span>{error.message}</span>}
          </div>
        )}
      />

      <button type="submit">Submit</button>
    </form>
  );
}

Dynamic Fields with useFieldArray

import { useForm, useFieldArray } from "react-hook-form";

function DynamicFieldsForm() {
  const { register, handleSubmit, control } = useForm({
    defaultValues: {
      users: [{ name: "", email: "" }],
    },
  });

  const { fields, append, remove } = useFieldArray({
    control,
    name: "users",
  });

  const onSubmit = (data) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      {fields.map((field, index) => (
        <div key={field.id}>
          <input
            {...register(`users.${index}.name`, {
              required: "Name is required",
            })}
            placeholder="Name"
          />
          <input
            {...register(`users.${index}.email`, {
              required: "Email is required",
            })}
            placeholder="Email"
          />
          <button type="button" onClick={() => remove(index)}>
            Remove
          </button>
        </div>
      ))}

      <button type="button" onClick={() => append({ name: "", email: "" })}>
        Add User
      </button>

      <button type="submit">Submit</button>
    </form>
  );
}

Async Form Submission

import { useForm } from "react-hook-form";

function AsyncSubmitForm() {
  const {
    register,
    handleSubmit,
    formState: { isSubmitting },
  } = useForm();

  const onSubmit = async (data) => {
    try {
      // Simulate API call
      await new Promise((resolve) => setTimeout(resolve, 2000));
      console.log("Form submitted:", data);
    } catch (error) {
      console.error("Submission failed:", error);
    }
  };

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input {...register("name", { required: true })} />
      <button type="submit" disabled={isSubmitting}>
        {isSubmitting ? "Submitting..." : "Submit"}
      </button>
    </form>
  );
}

Form with Context (FormProvider)

import { useForm, FormProvider, useFormContext } from "react-hook-form";

function NestedInput({ name, label }) {
  const {
    register,
    formState: { errors },
  } = useFormContext();

  return (
    <div>
      <label>{label}</label>
      <input {...register(name)} />
      {errors[name] && <span>{errors[name].message}</span>}
    </div>
  );
}

function ContextForm() {
  const methods = useForm();
  const onSubmit = (data) => console.log(data);

  return (
    <FormProvider {...methods}>
      <form onSubmit={methods.handleSubmit(onSubmit)}>
        <NestedInput name="firstName" label="First Name" />
        <NestedInput name="lastName" label="Last Name" />
        <button type="submit">Submit</button>
      </form>
    </FormProvider>
  );
}

Async Field Validation

import { useForm } from "react-hook-form";

function AsyncValidationForm() {
  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm();

  const checkUsernameAvailability = async (username) => {
    // Simulate API call to check username
    await new Promise((resolve) => setTimeout(resolve, 500));

    const takenUsernames = ["admin", "user", "test"];
    if (takenUsernames.includes(username.toLowerCase())) {
      return "Username is already taken";
    }
    return true;
  };

  const onSubmit = (data) => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        {...register("username", {
          required: "Username is required",
          validate: checkUsernameAvailability,
        })}
      />
      {errors.username && <span>{errors.username.message}</span>}

      <button type="submit">Submit</button>
    </form>
  );
}

Key Methods

useForm() Hook

const {
  register, // Register input fields
  handleSubmit, // Form submission handler
  formState, // Form state (errors, dirty, isValid, etc.)
  setValue, // Set field value programmatically
  getValues, // Get form values
  reset, // Reset form to default values
  trigger, // Trigger validation
  clearErrors, // Clear specific or all errors
  setError, // Set custom errors
  control, // Control object for Controller
} = useForm();

Form State

const {
  errors, // Validation errors
  dirty, // Form is dirty (has unsaved changes)
  dirtyFields, // Array of dirty field names
  isDirty, // Boolean indicating if form is dirty
  touched, // Array of touched field names
  touchedFields, // Object of touched field states
  isSubmitted, // Form has been submitted
  isSubmitting, // Form is currently submitting
  isValid, // Form passes all validations
  isValidating, // Form is currently validating
} = formState;

Common Validation Rules

register("fieldName", {
  required: "Field is required",
  minLength: { value: 3, message: "Minimum 3 characters" },
  maxLength: { value: 50, message: "Maximum 50 characters" },
  min: { value: 18, message: "Must be at least 18" },
  max: { value: 100, message: "Must be less than 100" },
  pattern: { value: /^\d+$/, message: "Numbers only" },
  validate: (value) => value === "expected" || "Custom validation failed",
});

平台分布

Claude Code

30.01%
按下载量换算25

windsurf

22.29%
按下载量换算19

trae

17.55%
按下载量换算15

OpenCode

13.23%
按下载量换算11

weavefox

8.35%
按下载量换算7

Codex

3.66%
按下载量换算3

安全审计

Gen Agent Trust Hub

通过

Socket

通过

Snyk

通过

权限和风险

需要联网

该 Skill 可能需要联网访问来源站点、仓库或外部 API;具体网络访问范围需要结合源码和 README 复核。

安装前确认

本站仅展示第三方公开信息,不托管安装包,不提供自动安装或运行环境。安装前应自行审查源码、依赖和命令行为。

继续浏览同类 Skills