跟着官方示例学习 @tanStack-form --- Simple

🌱 拆解核心概念

✅ useForm

useForm 是整个表单的控制中心,它定义了默认值、提交行为、验证逻辑等:

tsx 复制代码
const form = useForm({
  defaultValues: {
    firstName: '',
    lastName: '',
  },
  onSubmit: async ({ value }) => {
    console.log(value)
  },
})

你会获得一个 form 实例,拥有 .Field.handleSubmit().Subscribe() 等强大方法。

✅ form.Field

tsx 复制代码
<form.Field
  name="firstName"
  children={(field) => (
    <>
      <label htmlFor={field.name}>First Name:</label>
      <input
        id={field.name}
        name={field.name}
        value={field.state.value}
        onBlur={field.handleBlur}
        onChange={(e) => field.handleChange(e.target.value)}
      />
    </>
  )}
/>

你无需手动绑定 valueonChange ------ field 已为你封装好了完整的输入控件状态与行为,包含:

  • field.state.value: 当前值

  • field.handleChange: 更新值

  • field.handleBlur: 聚焦失效处理

  • field.name: 自动生成 name 属性

✅ form.Subscribe

订阅表单状态变化,比如是否可提交、是否正在提交等:

tsx 复制代码
<form.Subscribe
  selector={(state) => [state.canSubmit, state.isSubmitting]}
  children={([canSubmit, isSubmitting]) => (
    <>
      <button type="submit" disabled={!canSubmit}>
        {isSubmitting ? '...' : 'Submit'}
      </button>
      <button
        type="reset"
        onClick={(e) => {
          // Avoid unexpected resets of form elements (especially <select> elements)
          e.preventDefault()
          form.reset()
        }}
      >
        Reset
      </button>
    </>
  )}
/>

官方代码地址🔗: @tanStack/react-form

🧠 进阶:添加表单验证逻辑

写完最基础的表单后,很多人心里都有同一个声音:

"没有验证功能,它顶多只是个表单状态机罢了!"

别急,验证在 @tanStack/react-form 中不仅有,而且功能极其灵活、写法非常优雅。来看这一段👇:

tsx 复制代码
<form.Field
  name="firstName"
  validators={{
    onChange: ({ value }) =>
      !value
        ? 'A first name is required'
        : value.length < 3
        ? 'First name must be at least 3 characters'
        : undefined,

    onChangeAsyncDebounceMs: 500,
    onChangeAsync: async ({ value }) => {
      await new Promise((resolve) => setTimeout(resolve, 1000));
      return (
        value.includes('error') && 'No "error" allowed in first name'
      );
    },
  }}
  children={(field) => (
    <>
      <label htmlFor={field.name}>First Name:</label>
      <input
        id={field.name}
        name={field.name}
        value={field.state.value}
        onBlur={field.handleBlur}
        onChange={(e) => field.handleChange(e.target.value)}
      />
      <FieldInfo field={field} />
    </>
  )}
/>

✅ 支持同步和异步校验

你可以同时配置:

  • onChange:同步验证(即时反馈)

  • onChangeAsync:异步验证(如:服务器检查用户名是否存在)

  • onChangeAsyncDebounceMs:防抖,防止输入瞬间触发 N 次请求

✅ 错误信息展示组件 FieldInfo

tsx 复制代码
function FieldInfo({ field }: { field: AnyFieldApi }) {
  return (
    <>
      {field.state.meta.isTouched && !field.state.meta.isValid ? (
        <em>{field.state.meta.errors.join(',')}</em>
      ) : null}
      {field.state.meta.isValidating ? 'Validating...' : null}
    </>
  );
}

🌟 小提示:field.state.meta 包含了验证相关的各种状态标志

  • isTouched:是否被用户操作过

  • isValid:是否通过验证

  • isValidating:是否正在验证中

  • errors:错误信息列表(数组)

这样一来,我们可以精准控制什么时候展示错误、是否显示 loading 验证提示,而不是"盲目红框提示"。

✅ 校验逻辑完全可控

校验逻辑可以使用熟悉的 JS 函数,比如这个 async 校验,就像我们真实业务中可能碰到的一样:

tsx 复制代码
onChangeAsync: async ({ value }) => {
  await new Promise((r) => setTimeout(r, 1000));
  return value.includes('error') && 'No "error" allowed';
}

官方代码地址🔗: @tanStack/react-form

🌐 与 Zod 搭配使用

Zod API🔗

Zod 是一个强类型、链式语法的对象验证库,天然与 TypeScript 和 React 配合得天衣无缝。

🎯 示例:用 Zod 校验 age 字段

我们要验证用户的年龄必须 ≥ 13 岁,来看示例:

tsx 复制代码
import { z } from 'zod'

const userSchema = z.object({
  age: z.number().gte(13, 'You must be 13 to make an account'),
})

function App() {
  const form = useForm({
    defaultValues: {
      age: 0,
    },
    validators: {
      onChange: userSchema, // 传入 Zod schema
    },
  })

  return //....
}

🔍 Zod 校验发生在哪里?

你只需要将 schema 传给 validators.onChange,其余的事情 @tanStack/react-form 全帮你搞定:

tsx 复制代码
validators: {
  onChange: userSchema,
}
  • userSchema 会自动校验所有字段

  • 错误信息自动绑定到字段的 meta

  • 配合 <FieldInfo /> 显示错误信息轻轻松松

🔄 同时验证多个字段?

tsx 复制代码
const schema = z.object({
    firstName: z
    .string()
    .min(3, '[Zod] You must have a length of at least 3')
    .startsWith('A', "[Zod] First name must start with 'A'"),
  lastName: z.string().min(3, '[Zod] You must have a length of at least 3'),
})

然后直接作为 validators.onChange 传入:

tsx 复制代码
useForm({
  defaultValues: {
    firstName: '',
    lastName: '',
    age: 0,
  },
  validators: {
    onChange: userSchema,
  },
})

官方代码地址🔗: @tanStack/react-form

相关推荐
橙子家3 小时前
浏览器缓存之【身份与会话管理】:Cookies 和 Private state tokens
前端
最新资讯动态4 小时前
HDC 2026 | 对话鲸鸿动能:存量时代,品牌如何夺回营销“主动权”?
前端
最新资讯动态4 小时前
游戏出海,从产品走向体系
前端
最新资讯动态4 小时前
20人团队跑出百万DAU、大厂也来抢量:谁在鸿蒙生态跑出加速度
前端
最新资讯动态5 小时前
千万开发者背后,鸿蒙商业化的B面
前端
爱勇宝6 小时前
AI 时代:智商决定起点,情商决定走多远
前端·ai编程
kyriewen7 小时前
用了半年 Claude Code 后,我尝试关掉它写了一周代码——结果比想象中严重
前端·javascript·ai编程
IT_陈寒7 小时前
Vite的静态资源打包让我熬夜到三点,这坑千万别跳
前端·人工智能·后端
徐小夕8 小时前
万字拆解 JitWord:企业级实时协同文档底层架构 + 大模型 AI 融合完整实践
前端·vue.js·github
一份执念8 小时前
uni-app 小程序分包限制处理与主包体积优化实战
前端·微信小程序