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

KotlinJS接入react-hook-form如何正确绑定表单元素并触发提交验证

KotlinJS通过Dukat封装层适配react-hook-form的绑定问题

我尝试通过Dukat和封装层(Wrappers)让react-hook-form适配KotlinJS运行,目前的实现与遇到的问题如下:

封装层本身运行正常,我在控制台打印确认,调用的确实是库原生的useForm方法

最初的实现代码

我是如下方式使用useForm钩子的:

val useForm = useForm<ProfileModel>()

val register = useForm.register
val errors = useForm.formState.errors
val handleSubmit = useForm.handleSubmit

val registerInstagram = register("instagram", object : validateOptions<ProfileModel, Any> {
    override var required = true
    override var maxLength = 40
})

form(classes = "") {
    attrs.onSubmit = {
        it.preventDefault()
        console.log("Submit")
        handleSubmit({ data, ev ->
            console.log("On Submit " + data)
        }, { errors, ev ->
            console.log("On submit error " + errors)
        })
    }

    input(type = InputType.text,
        classes = "$defaultInputStyle mb-4") {
        attrs.placeholder = "Name"

        register("name", object : validateOptions<ProfileModel, Any> {
            override var required = true
            override var maxLength = 15
        })
    }

    input(type = InputType.text,
        classes = "$defaultInputStyle mb-4") {
        this.ref = registerInstagram.ref
        attrs {
            this.placeholder = "Instagram"
            this.onChange = registerInstagram.onChange
            this.onBlur = registerInstagram.onBlur
            this.name = registerInstagram.name
        }
    }

    button(classes = defaultButtonStyle, type = ButtonType.submit) {
        +"Submit"
    }
}

useForm本身运行正常,可以正确返回register、errors等所需属性,但无法与KotlinJS中的Input元素正确绑定。
register方法的返回值接口已做适配,符合React DOM的属性要求。常规React开发中使用<Input {...register}即可自动将返回的四个属性绑定到元素上,我定义的返回值接口如下:

external interface UseFormRegisterReturn {
    var onChange: ChangeEventHandler<*> // I changed this
    var onBlur: FocusEventHandler<*> // I changed this
    var ref: RefCallback<*> //I changed this
    var name: InternalFieldName
}

但点击提交按钮时,仅会打印"Submit"日志,useForm的handleSubmit方法没有执行,也没有任何数据输出,不清楚这套配置还存在什么缺失。

封装层其余相关代码

@JsName("useForm")
external fun <TFieldValues : FieldValues> useForm(props: `T$23`<TFieldValues> = definedExternally): UseFormReturn<TFieldValues, Any>


external interface UseFormReturn<TFieldValues : FieldValues, TContext : Any?> {
    var watch: UseFormWatch<TFieldValues>
    var getValues: UseFormGetValues<TFieldValues>
    var setError: UseFormSetError<TFieldValues>
    var clearErrors: UseFormClearErrors<TFieldValues>
    var setValue: UseFormSetValue<TFieldValues>
    var trigger: UseFormTrigger<TFieldValues>
    var formState: FormState<TFieldValues>
    var reset: UseFormReset<TFieldValues>
    var handleSubmit: UseFormHandleSubmit<TFieldValues>
    var unregister: UseFormUnregister<TFieldValues>
    var control: Control<TFieldValues, TContext>
    var register: UseFormRegister<TFieldValues>
    var setFocus: UseFormSetFocus<TFieldValues>
}

核心问题

我该如何将useForm的register方法正确绑定到我的表单元素上?


问题更新补充

我已经调整了部分配置,需要修改的点如下:

div("w-screen h-screen items-center justify-center p-4") {
    form(classes = "") {
        attrs.onSubmit = {
            it.preventDefault() // 1)

            handleSubmit({ data, ev ->
                console.log("On Submit ", data)
            }, { errors, ev ->
                console.log("On submit error ", errors)
            })(it) // 2)
        }

        input(type = InputType.text,
            classes = "$defaultInputStyle mb-4") {
            this.ref = registerInstagram.ref
            attrs { // 3)
                this.placeholder = "Instagram" 
                this.onChange = registerInstagram.onChange
                this.onBlur = registerInstagram.onBlur
                this.name = registerInstagram.name
            }
        }

        button(classes = defaultButtonStyle, type = ButtonType.submit) {
            +"Submit"
        }
    }
}

修改点说明:

  1. 阻止表单默认提交事件(如果不需要页面刷新)
  2. handleSubmit方法本身会返回一个需要传入事件参数的函数,我原来漏了调用这个返回的函数,需要写成handleSubmit()()的形式
  3. 完整绑定register返回的所有属性:onBlur、name、onChange和ref

调整后已经可以正常提交数据,但表单验证和错误提示功能仍然未生效。


解决方案

提交逻辑修复

你之前的核心提交问题已经通过修正handleSubmit的调用方式解决:react-hook-form的handleSubmit是高阶函数,接收成功/失败回调后返回实际的事件处理函数,必须主动传入表单事件触发执行,不能直接把它赋值给onSubmit就结束。

表单验证不生效修复

  • 检查所有带校验规则的字段绑定完整性:你代码里的name字段调用了register但是没有把返回的onChange/onBlur/ref/name绑定到对应input上,相当于这个字段完全没有被注册到react-hook-form的状态管理里,自然不会触发验证。所有字段都要和Instagram字段一样,完整绑定register返回的四个属性。
  • 适配formState响应性:KotlinJS的React封装对外部JS库的响应式对象监听可能存在适配问题,调用useForm时可以显式传入mode参数指定验证触发时机(比如mode = "onBlur"或者mode = "onChange"),同时确保你读取errors的逻辑是在React的重渲染流程里,或者用watch主动监听formState的变化触发UI更新。
  • 对齐验证规则接口:检查你定义的validateOptions接口是否和react-hook-form原生的校验参数完全对齐,有没有遗漏message等属性,或者字段名拼写错误导致校验规则没有被正确传入原生方法。
  • 修正ref泛型:你定义的UseFormRegisterReturn里的RefCallback不要用*通配符,明确指定为HTMLInputElement,避免ref绑定失败导致react-hook-form无法获取到表单元素的实例,进而无法触发校验。

内容的提问来源于stack exchange,提问作者Nikola-Milovic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 09:36:02