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

React Hook Form调用setValue预填字段提交时返回undefined如何解决

问题根因
  • 自定义的onChange覆盖了register返回的默认变更监听方法:react-hook-form依赖register注入的onChange同步表单字段状态,你自行定义的onChange={(e) => setNickname(e)}直接替换了该方法,导致表单状态无法更新,即使调用setValue也没法正确同步值。
  • 状态更新时序冲突:setDataForDropdown是React异步状态更新,同一个useEffect内调用完setDataForDropdown后立刻执行setValue时,下拉选项还未完成渲染,值无法和现有option匹配导致写入失败。
  • 非受控属性冲突:option上手动写的selected属性和react-hook-form的受控管理逻辑冲突,会干扰值的匹配。
修复方案

1. 修正onChange冲突

不要直接覆盖register返回的onChange,先执行react-hook-form的内置同步逻辑,再运行自定义逻辑:

<div className="item-input hal-input hal-margin-bottom-0 item-input-field not-empty-state">
  {/* 先把register返回的onChange单独提取出来 */}
  {(() => {
    const { onChange: rfOnChange, ...restRegister } = register("issuerAccount", {
      required: true,
    })
    return (
      <select
        disabled={
          activeStep === 2 || activeStep === 3 || dataForDropdown?.length == 1
        }
        {...restRegister}
        onChange={(e) => {
          rfOnChange(e) // 先执行react-hook-form的状态同步
          setNickname(e) // 再执行自定义逻辑
        }}
        className="hal-input-select account-selector "
        data-type="account"
      >
        <option value="">- Select -</option>
        {dataForDropdown?.map((x, i) => (
          {/* 删掉手动写的selected属性,值统一交给react-hook-form管理 */}
          <option value={x.id} key={x.id}>
            {x.id}
          </option>
        ))}
      </select>
    )
  })()}
  {errors.issuerAccount && (
    <span className="hal-validation_errors creditorAccount">
      {literals("newSubscription.field.requiredText")}
    </span>
  )}
</div>

2. 修正状态更新时序

把setValue的逻辑拆分到单独的useEffect中,等dataForDropdown更新完成后再触发值写入:

// 只处理下拉选项更新
useEffect(() => {
  if (issuer)
    setDataForDropdown(
      issuer.accounts.map((x) => ({
        id: x.accountNumber,
        text: x.branchName,
        selected: true,
      }))
    );
}, [issuer]);

// 等下拉选项更新后再处理预填充
useEffect(() => {
  if (issuer?.accounts?.length === 1 && dataForDropdown?.length === 1) {
    console.log(issuer.accounts[0].accountNumber);
    // 补充配置项确保状态更新生效
    setValue("issuerAccount", issuer.accounts[0].accountNumber, {
      shouldValidate: true,
      shouldDirty: true,
      shouldTouch: true
    });
  }
}, [issuer, dataForDropdown, setValue]);

内容的提问来源于stack exchange,提问作者Asad

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.05 03:06:03