UI 库

TanStack Form 与 UI 库的使用

TanStack Form 是一个无头库,为您提供完全的灵活性来按照您认为合适的方式进行样式设计。它与广泛的 UI 库兼容,包括 TailwindMaterial UIMantine,甚至是纯 CSS。

本指南重点介绍 Material UIMantine,但这些概念适用于您选择的任何 UI 库。

先决条件

在将 TanStack Form 与 UI 库集成之前,请确保在您的项目中安装了必要的依赖项:

  • 对于 Material UI,请按照其官方网站上的安装说明进行操作。
  • 对于 Mantine,请参考其文档

注意:虽然您可以混合搭配库,但通常建议坚持使用一个库以保持一致性并最小化膨胀。

Mantine 示例

以下是演示 TanStack Form 与 Mantine 组件集成的示例:

tsx
import { TextInput, Checkbox } from '@mantine/core'
import { useForm } from '@tanstack/react-form'

export default function App() {
  const { Field, handleSubmit, state } = useForm({
    defaultValues: {
      firstName: '',
      lastName: '',
      isChecked: false,
    },
    onSubmit: async ({ value }) => {
      // 处理表单提交
      console.log(value)
    },
  })

  return (
    <>
      <form
        onSubmit={(e) => {
          e.preventDefault()
          handleSubmit()
        }}
      >
        <Field
          name="firstName"
          children={({ state, handleChange, handleBlur }) => (
            <TextInput
              defaultValue={state.value}
              onChange={(e) => handleChange(e.target.value)}
              onBlur={handleBlur}
              placeholder="输入您的姓名"
            />
          )}
        />
        <Field
          name="isChecked"
          children={({ state, handleChange, handleBlur }) => (
            <Checkbox
              onChange={(e) => handleChange(e.target.checked)}
              onBlur={handleBlur}
              checked={state.value}
            />
          )}
        />
      </form>
      <div>
        <pre>{JSON.stringify(state.values, null, 2)}</pre>
      </div>
    </>
  )
}
import { TextInput, Checkbox } from '@mantine/core'
import { useForm } from '@tanstack/react-form'

export default function App() {
  const { Field, handleSubmit, state } = useForm({
    defaultValues: {
      firstName: '',
      lastName: '',
      isChecked: false,
    },
    onSubmit: async ({ value }) => {
      // 处理表单提交
      console.log(value)
    },
  })

  return (
    <>
      <form
        onSubmit={(e) => {
          e.preventDefault()
          handleSubmit()
        }}
      >
        <Field
          name="firstName"
          children={({ state, handleChange, handleBlur }) => (
            <TextInput
              defaultValue={state.value}
              onChange={(e) => handleChange(e.target.value)}
              onBlur={handleBlur}
              placeholder="输入您的姓名"
            />
          )}
        />
        <Field
          name="isChecked"
          children={({ state, handleChange, handleBlur }) => (
            <Checkbox
              onChange={(e) => handleChange(e.target.checked)}
              onBlur={handleBlur}
              checked={state.value}
            />
          )}
        />
      </form>
      <div>
        <pre>{JSON.stringify(state.values, null, 2)}</pre>
      </div>
    </>
  )
}
  • 首先,我们使用 TanStack 的 useForm 钩子并解构必要的属性。这一步是可选的;或者,如果您愿意,也可以使用 const form = useForm()。TypeScript 的类型推断确保无论采用哪种方法都能获得流畅的体验。
  • useForm 派生的 Field 组件接受多个属性,例如 validators。在此演示中,我们专注于两个主要属性:namechildren
    • name 属性标识每个 Field,例如我们示例中的 firstName
    • children 属性利用渲染属性的概念,允许我们在不需要不必要抽象的情况下集成组件。
  • TanStack 的设计严重依赖于渲染属性,在 Field 组件内提供对 children 的访问。这种方法完全是类型安全的。当与 Mantine 组件(如 TextInput)集成时,我们有选择地解构属性,如 state.valuehandleChangehandleBlur。这种选择性方法是由于 TextInput 和我们在 children 中获得的 field 之间类型的细微差异。
  • 通过遵循这些步骤,您可以无缝地将 Mantine 组件与 TanStack Form 集成。
  • 这种方法同样适用于其他组件,如 Checkbox,确保在不同 UI 元素之间保持一致的集成。

Usage with Material UI

The process for integrating Material UI components is similar. Here's an example using TextField and Checkbox from Material UI:

tsx
        <Field
            name="lastName"
            children={({ state, handleChange, handleBlur }) => {
              return (
                <TextField
                  id="filled-basic"
                  label="Filled"
                  variant="filled"
                  defaultValue={state.value}
                  onChange={(e) => handleChange(e.target.value)}
                  onBlur={handleBlur}
                  placeholder="输入您的姓氏"
                />
              );
            }}
          />

           <Field
            name="isMuiCheckBox"
            children={({ state, handleChange, handleBlur }) => {
              return (
                <MuiCheckbox
                  onChange={(e) => handleChange(e.target.checked)}
                  onBlur={handleBlur}
                  checked={state.value}
                />
              );
            }}
          />
        <Field
            name="lastName"
            children={({ state, handleChange, handleBlur }) => {
              return (
                <TextField
                  id="filled-basic"
                  label="Filled"
                  variant="filled"
                  defaultValue={state.value}
                  onChange={(e) => handleChange(e.target.value)}
                  onBlur={handleBlur}
                  placeholder="输入您的姓氏"
                />
              );
            }}
          />

           <Field
            name="isMuiCheckBox"
            children={({ state, handleChange, handleBlur }) => {
              return (
                <MuiCheckbox
                  onChange={(e) => handleChange(e.target.checked)}
                  onBlur={handleBlur}
                  checked={state.value}
                />
              );
            }}
          />
  • 集成方法与 Mantine 相同。
  • 主要区别在于特定的 Material UI 组件属性和样式选项。