跟着官方示例学习 @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

相关推荐
云小遥8 分钟前
Cornerstone3D 2.x升级调研
前端·数据可视化
李明卫杭州13 分钟前
浅谈JavaScript中Blob对象
前端·javascript
springfe010114 分钟前
Cesium 3D地图 图元 圆柱 图片实现
前端·cesium
meng半颗糖16 分钟前
vue3 双容器自动扩展布局 根据 内容的多少 动态定义宽度
前端·javascript·css·vue.js·elementui·vue3
yt9483217 分钟前
jquery和CSS3圆形倒计时特效
前端·css3·jquery
teeeeeeemo19 分钟前
CSS3 动画基础与技巧
前端·css·笔记·css3
年纪轻轻就扛不住22 分钟前
CSS3 渐变效果
前端·css·css3
Aisanyi26 分钟前
【鸿蒙开发】使用HMRouter路由的使用
前端·harmonyos
杉木笙31 分钟前
Flutter 代码雨实现(矩阵雨)DLC 多图层
前端·flutter
SouthernWind32 分钟前
Vista AI 演示—— 提示词优化功能
前端·vue.js