DaisyUI模态框中React Hook Form输入值无法注册的问题及解决
问题:DaisyUI模态框中React Hook Form无法注册输入值
问题描述
在React项目中结合DaisyUI与React Hook Form使用,点击按钮会弹出模态框显示编辑任务标题的表单,表单设置了必填验证规则。该表单在其他组件中正常工作,但在DaisyUI的模态框中提交时,控制台会出现required类型的错误。
相关错误信息
- 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" ]
- 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
相关产品推荐
相关产品推荐

