设计理念

每个成熟的项目都应该有指导其发展的理念。没有核心理念,开发可能会在无休止的决策中停滞不前,并因此导致 API 变弱。

本文档概述了驱动 TanStack Form 开发和功能集的核心原则。

升级统一的 API

API 总是伴随着权衡。因此,很容易通过不同的 API 将每组权衡提供给用户。然而,这可能导致 API 碎片化,更难学习和使用。

虽然这可能意味着更高的学习曲线,但它意味着您不必质疑内部使用哪个 API,或者在 API 之间切换时具有更高的认知开销。

表单需要灵活性

TanStack Form 旨在实现灵活性和可定制性。虽然许多表单可能遵循类似的模式,但总有例外;尤其是当表单是应用程序的核心组件时。

因此,TanStack Form 支持多种校验方法:

  • 时机自定义:您可以在失焦、更改、提交甚至挂载时进行校验。
  • 校验策略:您可以校验单个字段、整个表单或字段子集。
  • 自定义校验逻辑:您可以编写自己的校验逻辑或使用像 ZodValibot 这样的库。
  • 自定义错误消息:您可以通过从校验器返回任何对象来自定义每个字段的错误消息。
  • 异步校验:您可以异步校验字段,并为您处理诸如防抖和取消之类的常见实用程序。

受控组件大法好

在受控输入与非受控输入成为热门话题的世界中,TanStack Form 坚定地站在受控阵营。

这带来了许多优势:

  • 可预测:您可以随时预测表单的状态。
  • 更易于测试:您可以通过传入值��断言输出来轻松测试表单。
  • 非 DOM 支持:您可以将 TanStack Form 与 React Native、Three.js 框架适配器或任何其他框架渲染器一起使用。
  • 增强的条件逻辑:您可以根据表单状态轻松地有条件地显示/隐藏字段。
  • 调试:您可以轻松地将表单状态记录到控制台以调试问题。

泛型令人沮丧

在使用 TanStack Form 时,您永远不需要传递泛型或使用内部类型。这是因为我们设计的库可以从运行时默认值推断所有内容。

在编写足够正确的 TanStack Form 代码时,您应该无法区分 JavaScript 用法和 TypeScript 用法,除非您可能对运行时值进行任何类型转换。

代替:

typescript
useForm<MyForm>()
useForm<MyForm>()

你应该这样做:

typescript
interface Person {
  name: string
  age: number
}

const defaultPerson: Person = { name: 'Bill Luo', age: 24 }

useForm({
  defaultValues: defaultPerson,
})
interface Person {
  name: string
  age: number
}

const defaultPerson: Person = { name: 'Bill Luo', age: 24 }

useForm({
  defaultValues: defaultPerson,
})

库的解放力量

TanStack Form 的主要目标之一是您应该将其包装到自己的组件系统或设计系统中。

为了支持这一点,我们提供了许多实用程序,可以更轻松地构建您自己的组件和自定义钩子:

typescript
// 从您自己的库导出,其中包含用于表单的预绑定组件。
export const { useAppForm, withForm } = createFormHook(/* 选项 */)
// 从您自己的库导出,其中包含用于表单的预绑定组件。
export const { useAppForm, withForm } = createFormHook(/* 选项 */)

如果不这样做,您将向应用程序添加大量样板代码,并使表单的一致性和用户友好性降低。