标准答案

  1. 字段值、touched、dirty、errors、submitting 应该有清晰状态模型,避免散落在多个 useState 中。
  2. 同步校验适合必填、长度、格式和跨字段规则,提交前和字段交互时都可以触发。
  3. 异步校验适合用户名占用、邀请码有效性等服务端判断,需要防抖、取消和竞态处理。
  4. 提交态要禁用重复提交,保留服务端错误,并在成功后明确重置或跳转。
  5. React Hook Form、Formik、Zod、Yup 等工具可以减少样板,但仍要设计好错误展示和交互时机。

题目解析

这道题要覆盖用户体验和状态一致性。复杂表单最容易出问题的是异步校验竞态和提交中重复操作。

跨字段校验不能只看单个 input,例如确认密码、日期范围、金额上下限都需要整体校验。

服务端错误不应只弹 toast,字段级错误最好回填到对应字段,让用户知道该改哪里。

代码示例

下面用提交态阻止重复提交,并把服务端字段错误回填到表单。

TSX
async function handleSubmit(values: FormValues) {
  setSubmitting(true)
  setErrors({})

  try {
    await createAccount(values)
    navigate('/account/success')
  } catch (error) {
    setErrors(toFieldErrors(error))
  } finally {
    setSubmitting(false)
  }
}

return <button disabled={submitting}>提交</button>

常见误区

  • 异步校验没有取消或防抖,旧结果覆盖新输入的校验状态。
  • 只在提交时校验所有字段,用户输入过程中完全没有可恢复提示。
  • 提交失败只弹全局错误,不把字段错误映射回具体输入项。

作者信息