跟着官方示例学习 @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 分钟前
史诗级更新!sv-print虽然不是很强,但却是很能打的设计器组件
前端·产品
用户95251151401554 分钟前
最常用的JS加解密场景MD5
前端
Hilaku5 分钟前
“虚拟DOM”到底是什么?我们用300行代码来实现一个
前端·javascript·vue.js
打好高远球11 分钟前
mo契官网建设与SEO实践
前端
神仙别闹16 分钟前
基于Java+MySQL实现(Web)可扩展的程序在线评测系统
java·前端·mysql
心.c31 分钟前
react当中的this指向
前端·javascript·react.js
Java水解38 分钟前
Web API基础
前端
闲鱼不闲39 分钟前
实现iframe重定向通知父级页面跳转
前端
咸鱼青菜好好味40 分钟前
node的项目实战相关-2-前台接口
前端
春秋半夏41 分钟前
音乐播放、歌词滚动
前端·css