You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React18升级后react-hook-form的Controller与Reactstrap表单提交失败

React 18 + react-hook-form 表单提交失败问题解决

问题根源

你在使用Controller的render属性渲染Reactstrap的Input组件时,没有把react-hook-form提供的表单控件核心props(比如value、onChange)传递给Input。这会导致表单控件无法和react-hook-form的表单状态绑定,触发提交时,表单验证无法通过(控件值没有被正确收集),因此onSubmit函数不会执行。

解决方案

修改每个Controller的render函数,接收field参数并将其解构传递给Input组件,让控件和表单状态建立关联:

单个Controller修改示例

<Controller
  render={({ field }) => (
    <Input
      {...field} // 关键步骤:传递react-hook-form的控件props
      type="text"
      className="has-input input-lg"
      placeholder="Username"
      disabled={askToken}
    />
  )}
  name="username"
  control={control}
  rules={{ required: true }}
  defaultValue=""
/>

完整修改后的表单代码

<form onSubmit={handleSubmit(onSubmit)}>
  <FormGroup className="has-wrapper">
    <Controller
      render={({ field }) => (
        <Input
          {...field}
          type="text"
          className="has-input input-lg"
          placeholder="Username"
          disabled={askToken}
        />
      )}
      name="username"
      control={control}
      rules={{ required: true }}
      defaultValue=""
    />
    <span className="has-icon">
      <i className="ti-user" />
    </span>
  </FormGroup>
  <FormGroup className="has-wrapper">
    <Controller
      render={({ field }) => (
        <Input
          {...field}
          type="password" // 注意:原代码大写的"Password"改为小写,避免浏览器识别异常
          className="has-input input-lg"
          placeholder="Pass"
          disabled={askToken}
        />
      )}
      name="password"
      control={control}
      rules={{ required: true }}
      defaultValue=""
    />
    <span className="has-icon">
      <i className="ti-lock" />
    </span>
  </FormGroup>
  <FormGroup className="has-wrapper">
    <div className="row">
      <div className="w-75 col-12 col-md-4">
        <Controller
          render={({ field }) => (
            <Input
              {...field}
              type="text"
              className="has-input input-lg"
              placeholder="Security Code"
              disabled={askToken}
            />
          )}
          name="captcha"
          control={control}
          rules={{ required: true }}
          defaultValue=""
        />
      </div>
      <div className="w-25 col-12 col-md-6">{getImage()}</div>
    </div>
  </FormGroup>
  {/* 按钮部分保留原type="submit",无需改用onClick */}
  {askToken ? (
    <React.Fragment>
      <FormGroup className="mb-15">
        <Button
          variant="contained"
          className={`${
            token ? "btn-success" : "btn-warning"
          } btn-block w-100`}
          size="large"
          onClick={() => openUsbDevices()}
        >
          {token
            ? "Token condition text"
            : "Token condition text"}
        </Button>
      </FormGroup>
    </React.Fragment>
  ) : (
    <React.Fragment>
      <FormGroup className="mb-15">
        <Button
          type="submit"
          color="primary"
          className="btn-block w-100"
          variant="contained"
          size="large"
        >
          登录
        </Button>
      </FormGroup>

      <FormGroup className="mb-15">
        <Button
          variant="contained"
          className="btn-info btn-block w-100"
          size="large"
          onClick={onExternalLogin}
        >
          其他登录方式
        </Button>
      </FormGroup>
    </React.Fragment>
  )}
</form>

额外说明

  • 不要用onClick直接触发onSubmit,保持按钮的type="submit"是表单提交的标准实现,react-hook-form会自动处理验证和提交流程。
  • 密码输入框的type属性建议使用小写的password,避免出现浏览器兼容性问题。

内容的提问来源于stack exchange,提问作者Darius-htf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 19:10:08