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

DaisyUI模态框中React Hook Form输入值无法注册的问题及解决

问题:DaisyUI模态框中React Hook Form无法注册输入值

问题描述

在React项目中结合DaisyUI与React Hook Form使用,点击按钮会弹出模态框显示编辑任务标题的表单,表单设置了必填验证规则。该表单在其他组件中正常工作,但在DaisyUI的模态框中提交时,控制台会出现required类型的错误。

相关错误信息

  1. React Hook Form返回的错误信息:
taskTitle: Object { type: "required", message: "This field is required!", ref: input.grow }
  message: "This field is required!"
  ref: <input class="grow" type="text" placeholder="Fix Arch Linux" name="taskTitle">
    "__reactEvents$7sb6xdad22s": Set [ "invalid__bubble" ]
  1. React Hook Form返回的事件对象:
_reactName: "onSubmit"
​
_targetInst: null
​
bubbles: true
​
cancelable: true
​
currentTarget: null
​
defaultPrevented: true
​
eventPhase: 3
​
isDefaultPrevented: function functionThatReturnsTrue()​
isPropagationStopped: function functionThatReturnsFalse()
​
isTrusted: true
​
nativeEvent: submit { target: form, isTrusted: true, submitter: button.text-3xl.text-primary.shadow
, … }
​
target: <form>
​
timeStamp: 4223735
​
type: "submit"

相关代码

表单嵌套在DaisyUI模态框的modal-box中,核心代码如下:

function Tasks() {
  const [taskTitleEdit, setTaskTitleEdit] = useState(false);

  const { register, handleSubmit, reset } = useForm();

  function onSubmitTitle(data) {
    console.log("SUCCESS:", data);
    toast.success("Edited task title!");
    setTaskTitleEdit(false);
    reset();
  }
  function onErrorTitle(error) {
    toast.error("Error, check developer console!");
    console.log("FAILED!:");
    reset();
  }

  return (
    <div className="flex flex-col">
      {/* Task modal */}
      <div>
        <button
          className="cursor-pointer text-base"
          onClick={() =>
            document.getElementById(`my_modal_${index}`).showModal()
          }
        >
          {currentTask.task_title}
        </button>
        {/* -----MODAL BEGINNING----- */}
        <dialog
          id={`my_modal_${index}`}
          className="modal modal-bottom sm:modal-middle"
        >
          <div className="modal-box w-screen overflow-visible">
            <div className="mb-2 flex items-center gap-2">
              {/* TASK CHECKBOX */}
              <input
                type="checkbox"
                checked={currentTask.task_status}
                onChange={onChangeFunc}
                className="checkbox-primary checkbox checkbox-sm"
              />
              {!taskTitleEdit ? (
                /* TASK TITLE */
                <OptionsButton
                  tabIndex={index}
                  dropStyle={SELECT_STYLE}
                  options={taskTitleOperation}
                  style="text-lg font-bold cursor-pointer"
                  taskData={currentTask}
                >
                  {currentTask.task_title}
                </OptionsButton>
              ) : (
                // Task title edit form
                <>
                  <form
                    onSubmit={handleSubmit(
                      onSubmitTitle,
                      onErrorTitle,
                    )}
                  >
                    <label className="input input-bordered input-primary flex items-center gap-2">
                      <input
                        type="text"
                        className="grow"
                        placeholder={currentTask.task_title}
                        {...register("taskTitle", {
                          required: "This field is required!",
                        })}
                      />
                      <button
                        type="submit"
                        className="text-3xl text-primary shadow"
                      >
                        <CiSquareCheck />
                      </button>
                      <button
                        type="button"
                        className="text-3xl text-primary shadow"
                        onClick={() => handleEditTitle(currentTask)}
                      >
                        <CiSquareRemove />
                      </button>
                    </label>
                    {errors.taskTitle?.type && (
                      <span>{errors.taskTitle?.message}</span>
                    )}
                  </form>
                  <DevTool control={control} />
                </>
              )}
            </div>
            {/* 其余模态框内容省略 */}
          </div>
        </dialog>
        {/* -----MODAL END----- */}
      </div>
    </div>
  )
}

已尝试的解决方案

  • 在useForm钩子中设置和移除默认值;
  • 使用onChange = (e) => console.log(e.target.value)检测输入,RHF的onChange函数能正确记录值;
  • 移除表单中除提交按钮外的其他元素;
  • 将相同代码复制到无DaisyUI组件的其他组件中,可正常工作;
  • 在RHF表单的onSubmit和onError函数中设置event.preventDefault()。

解决过程与方案

排查记录(2024.08.12)

使用React Hook Form开发工具排查发现,尽管RHF的onChange函数能检测到输入值,但表单内的值无法被注册;输入框的touched属性会变为true,但值始终为空。

最终解决(2024.09.20)

通过使用任务ID动态命名表单字段,问题已解决,React Hook Form现在可以读取并验证输入值。示例代码如下:

<input
  placeholder={label}
  type="text"
  {...register(
    `taskLabel-${currentTask.id}`, // <--- 显式命名表单解决了问题
    {
      required: "Please enter a label!",
      minLength: {
        value: 3,
        message:
          "Label must be at least 3 characters long!",
      },
      maxLength: {
        value: 15,
        message:
          "Label must be less than 15 characters long!",
      },
    },
  )}/>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:44:51