useForm

这个 Hook 自 v1.7.0 版本起可用。

一个用来管理表单状态的 React Hook。

  • 与原生 <form /> 搭配使用时,使用非受控模式,表单的修改不会触发组件重渲染。(极致性能)
  • 与第三方的组件库搭配时,在常规的受控模式下运行良好,比如 shineout 等。

场景

  • 表单状态管理场景: 管理表单各字段的状态,实现表单整体或单字段更新
  • 表单验证与提交场景: 实现对表单数据的校验和提交操作
  • 动态表单场景: 动态增减表单项,灵活适应复杂表单需求

演示

源码
Gender:
Color:

用法

const {
  value,
  setValue,
  setFieldValue
  submit,
  reset,
  submitting,
  initialValue,
  handleChange,
  handleSubmit,
  handleReset,
  checkValidity,
  reportValidity,
  nativeProps,
} = useForm(options)

// 示例使用
const form = useForm({
  initialValues: {
    name: 'John Doe',
    email: 'hi@john.doe',
  },
  onSubmit: (form) => {
    console.log(form)
  },
})

// form.nativeProps 用来传递给原生表单元素的属性
// form.submitting 用来判断表单是否正在提交中

// form.submit() 用来提交表单
// form.reset() 用来重置表单
// form.setValue() 用来修改整个表单值
// form.setFieldValue() 用来设置单个表单值

// form.checkValidity() 验证表单,底层调用原生表单的 checkValidity 方法,仅对原生表单有效
// form.reportValidity() 验证并报告,底层调用原生表单的 reportValidity 方法,仅对原生表单有效

// 使用原生表单元素,非受控模式,但是内部控制了 form 的 ref
// 通过内置机制来保证执行 `setValue` 和 `setFieldValue` 操作时,UI 状态能够同步
return (
  <form {...form.nativeProps}>
    <label>姓名:<input type="text" name="name" /></label>
    <label>邮箱:<input type="email" name="email" /></label>
    <button disabled={form.submitting} type="submit">提交</button>
    <button type="reset">重置</button>
  </form>
)

// 使用组件库,受控模式,比如 shineout
return (
  <Form
    value={form.value}
    onChange={form.onChange}
    onSubmit={form.onSubmit}
    onReset={form.onReset}
    defaultValue={form.initialValue}
  >
    <Form.Item label="姓名"><Input type="text" name="name" /></Form.Item>
    <Form.Item label="邮箱"><Input type="email" name="email" /></Form.Item>
    <Form.Submit loading={form.submitting}>提交</Form.Submit>
    <Form.Reset>重置</Form.Reset>
  </Form>
)

源码

点击下方链接跳转 GitHub 查看源代码。

API

const form = useForm(options)

选项 Options

export interface UseFormOptions<FormState extends object> {
  /**
   * 表单的初始值
   *
   * @defaultValue {}
   */
  initialValue?: FormState
  /**
   * 表单项发生变化时的回调
   *
   * @defaultValue undefined
   */
  onChange?(form: FormState): void
  /**
   * 表单提交时的回调
   *
   * @defaultValue undefined
   */
  onSubmit?(form: FormState): void
  /**
   * 表单重置时的回调
   *
   * @defaultValue undefined
   */
  onReset?(): void
  /**
   * 当使用 `nativeProps` 时,提交表单是否阻止默认行为
   *
   * @defaultValue true
   */
  preventDefaultWhenSubmit?: boolean
  /**
   * 当重置时,是否额外触发 onChange 回调
   *
   * @defaultValue false
   * 
   * @deprecated 将在后续大版本中移除,请避免使用
   */
  triggerOnChangeWhenReset?: boolean
}

返回值

export type UseFormReturnsNativeProps = {
  /**
   * form 元素的 ref
   */
  ref: RefObject<HTMLFormElement | null>
  /**
   * 表单项发生变化时的回调
   */
  onChange(e: ChangeEvent<HTMLFormElement>): void
  /**
   * 表单提交时的回调
   */
  onSubmit(e: ChangeEvent<HTMLFormElement>): void
  /**
   * 表单重置时的回调
   */
  onReset(e: ChangeEvent<HTMLFormElement>): void
}

export interface UseFormReturns<FormState extends object> {
  /**
   * 表单是否正在提交操作中
   */
  submitting: boolean
  /**
   * 设置整个表单的值
   */
  setValue: ReactSetState<FormState>
  /**
   * 设置单个表单项的值
   */
  setFieldValue<Name extends keyof FormState>(name: Name, value: FormState[Name]): void
  /**
   * 重置表单
   */
  reset(): void
  /**
   * 提交表单
   */
  submit(): void
  /**
   * 当前表单的值
   */
  value: FormState
  /**
   * 表单元素的原生属性
   */
  initialValue: FormState
  /**
   * 表单项发生变化时的回调
   */
  handleChange(form: FormState): void
  /**
   * 表单提交时的回调
   */
  handleSubmit(form: FormState): void
  /**
   * 表单重置时的回调
   */
  handleReset(): void
  /**
   * 检查并报告表单的有效性,仅对原生表单有效
   */
  reportValidity(): boolean
  /**
   * 检查表单的有效性,仅对原生表单有效
   */
  checkValidity(): boolean
  /**
   * 传递给表单元素的原生属性
   */
  nativeProps: UseFormReturnsNativeProps
}